Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/admin/v3/init_dump.pb.h" 4 : #include "envoy/common/pure.h" 5 : #include "envoy/init/target.h" 6 : #include "envoy/init/watcher.h" 7 : 8 : #include "absl/container/flat_hash_map.h" 9 : 10 : namespace Envoy { 11 : namespace Init { 12 : 13 : /** 14 : * Init::Manager coordinates initialization of one or more "targets." A typical flow would be: 15 : * 16 : * - One or more initialization targets are registered with a manager using `add`. 17 : * - The manager is told to `initialize` all its targets, given a Watcher to notify when all 18 : * registered targets are initialized. 19 : * - Each target will initialize, either immediately or asynchronously, and will signal 20 : * `ready` to the manager when initialized. 21 : * - When all targets are initialized, the manager signals `ready` to the watcher it was given 22 : * previously. 23 : * 24 : * Since there are several entities involved in this flow -- the owner of the manager, the targets 25 : * registered with the manager, and the manager itself -- it may be difficult or impossible in some 26 : * cases to guarantee that their lifetimes line up correctly to avoid use-after-free errors. The 27 : * interface design here in Init allows implementations to avoid the issue: 28 : * 29 : * - A Target can only be initialized via a TargetHandle, which acts as a weak reference. 30 : * Attempting to initialize a destroyed Target via its handle has no ill effects. 31 : * - Likewise, a Watcher can only be notified that initialization was complete via a 32 : * WatcherHandle, which acts as a weak reference as well. 33 : * 34 : * See target.h and watcher.h, as well as implementation in source/common/init for details. 35 : */ 36 : struct Manager { 37 2013 : virtual ~Manager() = default; 38 : 39 : /** 40 : * The manager's state, used e.g. for reporting in the admin server. 41 : */ 42 : enum class State { 43 : /** 44 : * Targets have not been initialized. 45 : */ 46 : Uninitialized, 47 : /** 48 : * Targets are currently being initialized. 49 : */ 50 : Initializing, 51 : /** 52 : * All targets have been initialized. 53 : */ 54 : Initialized 55 : }; 56 : 57 : /** 58 : * @return the current state of the manager. 59 : */ 60 : virtual State state() const PURE; 61 : 62 : /** 63 : * Register an initialization target. If the manager's current state is uninitialized, the target 64 : * will be saved for invocation later, when `initialize` is called. If the current state is 65 : * initializing, the target will be invoked immediately. It is an error to register a target with 66 : * a manager that is already in initialized state. 67 : * @param target the target to be invoked when initialization begins. 68 : */ 69 : virtual void add(const Target& target) PURE; 70 : 71 : /** 72 : * Start initialization of all previously registered targets, and notify the given Watcher when 73 : * initialization is complete. It is an error to call initialize on a manager that is already in 74 : * initializing or initialized state. If the manager contains no targets, initialization completes 75 : * immediately. 76 : * @param watcher the watcher to notify when initialization is complete. 77 : */ 78 : virtual void initialize(const Watcher& watcher) PURE; 79 : 80 : /** 81 : * Add unready targets information into the config dump. 82 : */ 83 : virtual void dumpUnreadyTargets(envoy::admin::v3::UnreadyTargetsDumps& dumps) PURE; 84 : }; 85 : 86 : } // namespace Init 87 : } // namespace Envoy