Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : // SPDX-License-Identifier: Apache-2.0
3 : :
4 : : #pragma once
5 : :
6 : : #include <atomic>
7 : : #include <cstdint>
8 : :
9 : : #include <hpactor/actor/drain_config.hpp>
10 : : #include <hpactor/actor/lifecycle_state.hpp>
11 : : #include <hpactor/types/types.hpp> // complete error type needed for value members
12 : :
13 : : namespace hpactor {
14 : :
15 : : class LifecycleActor {
16 : : public:
17 : 37 : LifecycleActor()
18 : 37 : : state_(static_cast<uint8_t>(LifecycleState::kStarting)),
19 : 37 : incarnation_(0) {}
20 : 37 : virtual ~LifecycleActor() = default;
21 : :
22 : : // ── State queries ──────────────────────────────────
23 : 242 : LifecycleState state() const noexcept {
24 : 484 : return static_cast<LifecycleState>(state_.load(std::memory_order_acquire));
25 : : }
26 : 11 : bool accepts_user_msgs() const noexcept {
27 : 11 : return kStateMachine[static_cast<int>(state())].accepts_user_msgs;
28 : : }
29 : 5 : bool accepts_system_msgs() const noexcept {
30 : 5 : return kStateMachine[static_cast<int>(state())].accepts_system_msgs;
31 : : }
32 : 7 : const char* state_string() const noexcept {
33 : 7 : return kStateMachine[static_cast<int>(state())].name;
34 : : }
35 : 4 : uint64_t incarnation() const noexcept {
36 : 8 : return incarnation_.load(std::memory_order_acquire);
37 : : }
38 : 3 : void bump_incarnation() {
39 : 3 : incarnation_.fetch_add(1, std::memory_order_relaxed);
40 : 3 : }
41 : :
42 : : // ── Failure reason ─────────────────────────────────
43 : : // Set before transition(kFailed) so on_fail() receives the real error.
44 : 0 : void set_failure_reason(error err) {
45 : 0 : failure_reason_ = err;
46 : 0 : }
47 : : error failure_reason() const {
48 : : return failure_reason_;
49 : : }
50 : :
51 : : // ── Drain config accessors ──────────────────────────
52 : 39 : DrainConfig drain_config() const noexcept {
53 : 39 : return drain_config_;
54 : : }
55 : 21 : void set_drain_config(DrainConfig cfg) noexcept {
56 : 21 : drain_config_ = cfg;
57 : 21 : }
58 : :
59 : : // ── Transition ─────────────────────────────────────
60 : : // Validates that `to` is a legal transition from the current state,
61 : : // performs a CAS, and invokes the corresponding virtual hook.
62 : : // Returns false if the transition is illegal or CAS fails.
63 : : bool transition(LifecycleState to);
64 : :
65 : : // ── Virtual hooks (default = no-op) ────────────────
66 : 25 : virtual void on_start() {}
67 : 8 : virtual void on_drain() {}
68 : 1 : virtual void on_drain_timeout() {}
69 : 15 : virtual void on_stop() {}
70 : 16 : virtual void on_deactivate() {}
71 : : virtual void on_fail(error err);
72 : 0 : virtual void on_recover() {}
73 : 0 : virtual void on_restart() {}
74 : :
75 : : // NOTE: LifecycleActor does NOT override as_lifecycle().
76 : : // Each lifecycle actor class must explicitly override
77 : : // AbstractActor::as_lifecycle() to return this. Example:
78 : : // LifecycleActor* as_lifecycle() override { return this; }
79 : : // This is required because LifecycleActor does not inherit from
80 : : // AbstractActor, so it cannot override its virtual method directly.
81 : :
82 : : protected:
83 : : std::atomic<uint8_t> state_;
84 : : std::atomic<uint64_t> incarnation_;
85 : : error failure_reason_{0};
86 : : DrainConfig drain_config_{};
87 : : };
88 : :
89 : : } // namespace hpactor
|