Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : //
3 : : // Licensed under the Apache License, Version 2.0 (the "License");
4 : : // you may not use this file except in compliance with the License.
5 : : // You may obtain a copy of the License at
6 : : //
7 : : // http://www.apache.org/licenses/LICENSE-2.0
8 : : //
9 : : // Unless required by applicable law or agreed to in writing, software
10 : : // distributed under the License is distributed on an "AS IS" BASIS,
11 : : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : // See the License for the specific language governing permissions and
13 : : // limitations under the License.
14 : :
15 : : #pragma once
16 : :
17 : : #include <hpactor/actor/typed_message.hpp>
18 : : #include <hpactor/ref/actor_address.hpp>
19 : : #include <hpactor/types/types.hpp>
20 : :
21 : : #include <chrono>
22 : : #include <cstdint>
23 : :
24 : : namespace hpactor::mailbox {
25 : :
26 : : struct MailboxCapacity {
27 : : uint32_t max_messages = 1024;
28 : : uint64_t max_bytes = 0;
29 : : };
30 : :
31 : : enum class OverflowPolicy : uint8_t {
32 : : RejectNewest,
33 : : DropNewest,
34 : : DropOldest,
35 : : DropLowestPriority,
36 : : DeadLetter,
37 : : SpillToOverflowQueue,
38 : : SignalOnly,
39 : : BlockWhenAllowed,
40 : : };
41 : :
42 : : enum class BackpressureMode : uint8_t {
43 : : Disabled,
44 : : LocalSignal,
45 : : RemoteSignal,
46 : : LocalAndRemoteSignal,
47 : : };
48 : :
49 : : enum class MailboxPressureState : uint8_t {
50 : : Normal,
51 : : SoftPressure,
52 : : HardPressure,
53 : : Recovering,
54 : : };
55 : :
56 : : struct MailboxConfig {
57 : : MailboxCapacity capacity;
58 : : uint8_t priority_levels = 4;
59 : : OverflowPolicy overflow_policy = OverflowPolicy::RejectNewest;
60 : : BackpressureMode backpressure_mode = BackpressureMode::LocalAndRemoteSignal;
61 : : double high_watermark = 0.80;
62 : : double low_watermark = 0.50;
63 : : uint32_t protected_system_messages = 32;
64 : : uint32_t max_overflow_depth = 0;
65 : : uint32_t signal_min_interval_ms = 100;
66 : : bool priority_aware = false;
67 : : bool enable_dead_letters = true;
68 : : };
69 : :
70 : : struct MessagePriority {
71 : : uint8_t value = 0;
72 : : };
73 : :
74 : : struct DeliveryOptions {
75 : : bool no_drop = false;
76 : : bool allow_blocking = false;
77 : : bool emit_backpressure = true;
78 : : uint64_t message_id = 0;
79 : : uint32_t flags = 0;
80 : : };
81 : :
82 : : struct MailboxEnvelopeMeta {
83 : : ActorAddress sender;
84 : : TypeTag type_tag = TypeTag::Invalid;
85 : : uint64_t message_id = 0;
86 : : uint8_t priority = 0;
87 : : int64_t deadline_ns = INT64_MAX;
88 : : uint32_t flags = 0;
89 : : uint64_t estimated_bytes = 0;
90 : : uint64_t sequence = 0;
91 : : };
92 : :
93 : : enum class EnqueueResultCode : uint8_t {
94 : : Accepted,
95 : : AcceptedWithSoftPressure,
96 : : Rejected,
97 : : DroppedNewest,
98 : : DroppedExisting,
99 : : ReroutedToDeadLetter,
100 : : ReroutedToOverflow,
101 : : MailboxClosed,
102 : : ActorNotFound,
103 : : };
104 : :
105 : : struct EnqueueResult {
106 : : EnqueueResultCode code = EnqueueResultCode::Accepted;
107 : : ActorId target;
108 : : uint32_t depth = 0;
109 : : uint32_t capacity = 0;
110 : : double pressure_ratio = 0.0;
111 : 4 : std::chrono::milliseconds retry_after{0};
112 : : TypeTag affected_type = TypeTag::Invalid;
113 : : uint64_t affected_message_id = 0;
114 : :
115 : : [[nodiscard]] EnqueueResultCode status() const noexcept {
116 : : return code;
117 : : }
118 : : [[nodiscard]] bool ok() const noexcept {
119 : : return accepted();
120 : : }
121 : :
122 : 120654 : [[nodiscard]] bool accepted() const noexcept {
123 : 240125 : return code == EnqueueResultCode::Accepted ||
124 : 240125 : code == EnqueueResultCode::AcceptedWithSoftPressure;
125 : : }
126 : :
127 : 2 : [[nodiscard]] bool retryable() const noexcept {
128 : 3 : return code == EnqueueResultCode::Rejected ||
129 : 3 : code == EnqueueResultCode::MailboxClosed ||
130 : 3 : code == EnqueueResultCode::ReroutedToOverflow;
131 : : }
132 : : };
133 : :
134 : : enum class BackpressureReason : uint8_t {
135 : : HighWatermark,
136 : : HardCapacity,
137 : : ByteCapacity,
138 : : OverflowPolicy,
139 : : NodeMemoryPressure,
140 : : };
141 : :
142 : : struct BackpressureSignal {
143 : : ActorAddress target;
144 : : ActorAddress sender;
145 : : BackpressureReason reason = BackpressureReason::HighWatermark;
146 : : uint32_t depth = 0;
147 : : uint32_t capacity = 0;
148 : : uint64_t bytes = 0;
149 : : uint64_t byte_capacity = 0;
150 : : double pressure_ratio = 0.0;
151 : : std::chrono::milliseconds retry_after{0};
152 : : uint64_t sequence = 0;
153 : : };
154 : :
155 : 120417 : [[nodiscard]] constexpr bool is_system_message(TypeTag tag) noexcept {
156 : 120417 : return static_cast<uint32_t>(tag) > 0 &&
157 : 120417 : static_cast<uint32_t>(tag) < static_cast<uint32_t>(TypeTag::User);
158 : : }
159 : :
160 : : [[nodiscard]] inline uint64_t
161 : 121816 : estimate_message_bytes(const TypedMessage& msg) noexcept {
162 : 121816 : return sizeof(TypedMessage) + msg.payload().size();
163 : : }
164 : :
165 : 8 : inline const char* to_string(OverflowPolicy policy) noexcept {
166 : 8 : switch (policy) {
167 : 4 : case OverflowPolicy::RejectNewest:
168 : 4 : return "reject_newest";
169 : 3 : case OverflowPolicy::DropNewest:
170 : 3 : return "drop_newest";
171 : 0 : case OverflowPolicy::DropOldest:
172 : 0 : return "drop_oldest";
173 : 0 : case OverflowPolicy::DropLowestPriority:
174 : 0 : return "drop_lowest_priority";
175 : 1 : case OverflowPolicy::DeadLetter:
176 : 1 : return "dead_letter";
177 : 0 : case OverflowPolicy::SpillToOverflowQueue:
178 : 0 : return "spill_to_overflow_queue";
179 : 0 : case OverflowPolicy::SignalOnly:
180 : 0 : return "signal_only";
181 : 0 : case OverflowPolicy::BlockWhenAllowed:
182 : 0 : return "block_when_allowed";
183 : : }
184 : 0 : return "reject_newest";
185 : : }
186 : :
187 : 8 : inline const char* to_string(MailboxPressureState state) noexcept {
188 : 8 : switch (state) {
189 : 0 : case MailboxPressureState::Normal:
190 : 0 : return "normal";
191 : 8 : case MailboxPressureState::SoftPressure:
192 : 8 : return "soft_pressure";
193 : 0 : case MailboxPressureState::HardPressure:
194 : 0 : return "hard_pressure";
195 : 0 : case MailboxPressureState::Recovering:
196 : 0 : return "recovering";
197 : : }
198 : 0 : return "normal";
199 : : }
200 : :
201 : : } // namespace hpactor::mailbox
|