Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/init/manager_impl.cc
Line
Count
Source (jump to first uncovered line)
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
72.5k
      watcher_(name_, [this](absl::string_view target_name) { onTargetReady(target_name); }) {}
14
15
23.7k
Manager::State ManagerImpl::state() const { return state_; }
16
17
8.65k
void ManagerImpl::add(const Target& target) {
18
8.65k
  ++count_;
19
8.65k
  TargetHandlePtr target_handle(target.createHandle(name_));
20
8.65k
  ++target_names_count_[target.name()];
21
8.65k
  switch (state_) {
22
6.68k
  case State::Uninitialized:
23
    // If the manager isn't initialized yet, save the target handle to be initialized later.
24
6.68k
    ENVOY_LOG(debug, "added {} to {}", target.name(), name_);
25
6.68k
    target_handles_.push_back(std::move(target_handle));
26
6.68k
    return;
27
1.97k
  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
1.97k
    target_handle->initialize(watcher_);
33
1.97k
    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
8.65k
  }
38
8.65k
}
39
40
9.56k
void ManagerImpl::initialize(const Watcher& watcher) {
41
  // If the manager is already initializing or initialized, consider this a programming error.
42
9.56k
  ASSERT(state_ == State::Uninitialized, fmt::format("attempted to initialize {} twice", name_));
43
44
  // Create a handle to notify when initialization is complete.
45
9.56k
  watcher_handle_ = watcher.createHandle(name_);
46
47
9.56k
  if (count_ == 0) {
48
    // If we have no targets, initialization trivially completes. This can happen, and is fine.
49
7.15k
    ENVOY_LOG(debug, "{} contains no targets", name_);
50
7.15k
    ready();
51
7.15k
  } else {
52
    // If we have some targets, start initialization...
53
2.40k
    ENVOY_LOG(debug, "{} initializing", name_);
54
2.40k
    state_ = State::Initializing;
55
56
    // Attempt to initialize each target. If a target is unavailable, treat it as though it
57
    // completed immediately.
58
3.53k
    for (const auto& target_handle : target_handles_) {
59
3.53k
      if (!target_handle->initialize(watcher_)) {
60
0
        onTargetReady(target_handle->name());
61
0
      }
62
3.53k
    }
63
2.40k
  }
64
9.56k
}
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
4.11k
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
4.11k
  ASSERT(count_ != 0,
78
4.11k
         fmt::format("{} called back by target after initialization complete", target_name));
79
80
  // Decrease target_name count by 1.
81
4.11k
  ASSERT(target_names_count_.find(target_name) != target_names_count_.end());
82
4.11k
  if (--target_names_count_[target_name] == 0) {
83
4.10k
    target_names_count_.erase(target_name);
84
4.10k
  }
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
4.11k
  if (--count_ == 0) {
89
2.10k
    ready();
90
2.10k
  }
91
4.11k
}
92
93
9.26k
void ManagerImpl::ready() {
94
9.26k
  state_ = State::Initialized;
95
9.26k
  watcher_handle_->ready();
96
9.26k
}
97
98
} // namespace Init
99
} // namespace Envoy