LCOV - code coverage report
Current view: top level - source/common/init - manager_impl.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 45 57 78.9 %
Date: 2024-01-05 06:35:25 Functions: 7 8 87.5 %

          Line data    Source code
       1             : #include "source/common/init/manager_impl.h"
       2             : 
       3             : #include <functional>
       4             : 
       5             : #include "source/common/common/assert.h"
       6             : #include "source/common/init/watcher_impl.h"
       7             : 
       8             : namespace Envoy {
       9             : namespace Init {
      10             : 
      11             : ManagerImpl::ManagerImpl(absl::string_view name)
      12             :     : name_(fmt::format("init manager {}", name)),
      13        1962 :       watcher_(name_, [this](absl::string_view target_name) { onTargetReady(target_name); }) {}
      14             : 
      15        1461 : Manager::State ManagerImpl::state() const { return state_; }
      16             : 
      17         314 : void ManagerImpl::add(const Target& target) {
      18         314 :   ++count_;
      19         314 :   TargetHandlePtr target_handle(target.createHandle(name_));
      20         314 :   ++target_names_count_[target.name()];
      21         314 :   switch (state_) {
      22         220 :   case State::Uninitialized:
      23             :     // If the manager isn't initialized yet, save the target handle to be initialized later.
      24         220 :     ENVOY_LOG(debug, "added {} to {}", target.name(), name_);
      25         220 :     target_handles_.push_back(std::move(target_handle));
      26         220 :     return;
      27          94 :   case State::Initializing:
      28             :     // If the manager is already initializing, initialize the new target immediately. Note that
      29             :     // it's important in this case that count_ was incremented above before calling the target,
      30             :     // because if the target calls the init manager back immediately, count_ will be decremented
      31             :     // here (see the definition of watcher_ above).
      32          94 :     target_handle->initialize(watcher_);
      33          94 :     return;
      34           0 :   case State::Initialized:
      35             :     // If the manager has already completed initialization, consider this a programming error.
      36           0 :     ASSERT(false, fmt::format("attempted to add {} to initialized {}", target.name(), name_));
      37         314 :   }
      38         314 : }
      39             : 
      40         554 : void ManagerImpl::initialize(const Watcher& watcher) {
      41             :   // If the manager is already initializing or initialized, consider this a programming error.
      42         554 :   ASSERT(state_ == State::Uninitialized, fmt::format("attempted to initialize {} twice", name_));
      43             : 
      44             :   // Create a handle to notify when initialization is complete.
      45         554 :   watcher_handle_ = watcher.createHandle(name_);
      46             : 
      47         554 :   if (count_ == 0) {
      48             :     // If we have no targets, initialization trivially completes. This can happen, and is fine.
      49         339 :     ENVOY_LOG(debug, "{} contains no targets", name_);
      50         339 :     ready();
      51         371 :   } else {
      52             :     // If we have some targets, start initialization...
      53         215 :     ENVOY_LOG(debug, "{} initializing", name_);
      54         215 :     state_ = State::Initializing;
      55             : 
      56             :     // Attempt to initialize each target. If a target is unavailable, treat it as though it
      57             :     // completed immediately.
      58         215 :     for (const auto& target_handle : target_handles_) {
      59         215 :       if (!target_handle->initialize(watcher_)) {
      60           0 :         onTargetReady(target_handle->name());
      61           0 :       }
      62         215 :     }
      63         215 :   }
      64         554 : }
      65             : 
      66           0 : void ManagerImpl::dumpUnreadyTargets(envoy::admin::v3::UnreadyTargetsDumps& unready_targets_dumps) {
      67           0 :   auto& message = *unready_targets_dumps.mutable_unready_targets_dumps()->Add();
      68           0 :   message.set_name(name_);
      69           0 :   for (const auto& [target_name, count] : target_names_count_) {
      70           0 :     UNREFERENCED_PARAMETER(count);
      71           0 :     message.add_target_names(target_name);
      72           0 :   }
      73           0 : }
      74             : 
      75         296 : void ManagerImpl::onTargetReady(absl::string_view target_name) {
      76             :   // If there are no remaining targets and one mysteriously calls us back, this manager is haunted.
      77         296 :   ASSERT(count_ != 0,
      78         296 :          fmt::format("{} called back by target after initialization complete", target_name));
      79             : 
      80             :   // Decrease target_name count by 1.
      81         296 :   ASSERT(target_names_count_.find(target_name) != target_names_count_.end());
      82         296 :   if (--target_names_count_[target_name] == 0) {
      83         296 :     target_names_count_.erase(target_name);
      84         296 :   }
      85             : 
      86             :   // If there are no uninitialized targets remaining when called back by a target, that means it was
      87             :   // the last. Signal `ready` to the handle we saved in `initialize`.
      88         296 :   if (--count_ == 0) {
      89         202 :     ready();
      90         202 :   }
      91         296 : }
      92             : 
      93         541 : void ManagerImpl::ready() {
      94         541 :   state_ = State::Initialized;
      95         541 :   watcher_handle_->ready();
      96         541 : }
      97             : 
      98             : } // namespace Init
      99             : } // namespace Envoy

Generated by: LCOV version 1.15