NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
host_admission.h
Go to the documentation of this file.
1
10#pragma once
11
12#include <neograph/api.h>
14
15#include <asio/awaitable.hpp>
16
17#include <chrono>
18#include <cstdint>
19#include <memory>
20#include <optional>
21#include <stdexcept>
22#include <string>
23#include <string_view>
24#include <vector>
25
26namespace neograph {
27
29struct NEOGRAPH_API HostResourceVector {
30 std::uint64_t cpu_millis = 0;
31 std::uint64_t memory_bytes = 0;
32 std::uint64_t gpu_slots = 0;
33 std::uint64_t gpu_memory_bytes = 0;
34 std::uint64_t processes = 0;
35 std::uint64_t threads = 0;
36 std::uint64_t file_descriptors = 0;
37 std::uint64_t disk_bytes = 0;
38 std::uint64_t network_connections = 0;
39 std::uint64_t tool_slots = 0;
40 std::uint64_t provider_requests = 0;
41 std::uint64_t model_tokens = 0;
42 std::uint64_t monetary_microunits = 0;
43 std::uint64_t wall_time_ms = 0;
44
45 bool operator==(const HostResourceVector&) const = default;
46
47 [[nodiscard]] bool empty() const noexcept;
49 [[nodiscard]] bool fits_within(const HostResourceVector& limit) const noexcept;
50 [[nodiscard]] static HostResourceVector componentwise_min(const HostResourceVector& lhs,
51 const HostResourceVector& rhs) noexcept;
53 [[nodiscard]] static HostResourceVector saturating_add(const HostResourceVector& lhs,
54 const HostResourceVector& rhs) noexcept;
57 const HostResourceVector& rhs) noexcept;
58};
59
60enum class HostResourceConfidence : std::uint8_t {
61 Measured,
62 Estimated,
63 ConservativeFallback,
64};
65
66NEOGRAPH_API std::string_view to_string(HostResourceConfidence confidence) noexcept;
67
69struct NEOGRAPH_API HostResourceEvidence {
70 std::string source;
71 HostResourceConfidence confidence = HostResourceConfidence::ConservativeFallback;
72 std::int64_t observed_at_ms = 0;
73 bool cgroup_limited = false;
74
75 bool operator==(const HostResourceEvidence&) const = default;
76};
77
87
92class NEOGRAPH_API HostResourceProfile {
93public:
94 static constexpr std::uint32_t SCHEMA_VERSION = 1;
95
103 static HostResourceProfile intersect(const std::vector<HostResourceProfile>& profiles,
104 std::string profile_id);
107 std::string profile_id) const;
108 const std::string& profile_id() const noexcept;
109 const HostResourceVector& capacity() const noexcept;
110 const HostResourceVector& safety_reserve() const noexcept;
111 HostResourceVector available_capacity() const noexcept;
112 const HostResourceEvidence& evidence() const noexcept;
113 std::string serialize_canonical() const;
114
115private:
118};
119
120enum class HostPressureLevel : std::uint8_t {
121 Normal,
122 Elevated,
123 Critical,
124};
125NEOGRAPH_API std::string_view to_string(HostPressureLevel level) noexcept;
126
127struct NEOGRAPH_API HostPressureSample {
128 HostPressureLevel level = HostPressureLevel::Normal;
129 std::int64_t observed_at_ms = 0;
130 std::string source;
131};
132
133enum class HostAdmissionFailure : std::uint8_t {
134 InvalidRequest,
135 CapacityExceeded,
136 QueueFull,
137 QueueTimeout,
138 Shutdown,
139};
140
141NEOGRAPH_API std::string_view to_string(HostAdmissionFailure failure) noexcept;
142
143class NEOGRAPH_API HostAdmissionError final : public std::runtime_error {
144public:
145 HostAdmissionError(HostAdmissionFailure failure, std::string detail);
146 [[nodiscard]] HostAdmissionFailure failure() const noexcept;
147
148private:
149 HostAdmissionFailure failure_;
150};
151
153struct NEOGRAPH_API HostAdmissionRequest {
154 std::string owner_scope;
155 std::string operation_id;
156 HostResourceVector resources;
158 std::uint8_t priority = 0;
160 std::uint32_t max_pending = 0;
161 std::chrono::milliseconds queue_timeout{0};
163 std::uint8_t fairness_weight = 1;
164};
165
166struct NEOGRAPH_API HostAdmissionSnapshot {
167 HostResourceProfile profile = HostResourceProfile::detect_current();
168 HostResourceVector reserved;
169 HostResourceVector available;
170 std::uint32_t queued = 0;
171 bool overcommitted = false;
172 HostPressureLevel pressure = HostPressureLevel::Normal;
173 std::uint8_t pressure_scale_percent = 100;
174 std::int64_t pressure_changed_at_ms = 0;
175 std::string pressure_source;
176};
177
178struct NEOGRAPH_API HostAdmissionControllerConfig {
179 std::optional<HostResourceProfile> profile;
180 std::uint32_t max_pending = 1024;
182 std::chrono::milliseconds aging_quantum{100};
184 std::uint8_t elevated_capacity_percent = 75;
186 std::uint8_t critical_capacity_percent = 50;
188 std::uint8_t recovery_step_percent = 10;
190 std::chrono::milliseconds recovery_quiet_period{5000};
191};
192
193namespace detail {
194class HostAdmissionControllerImpl;
195}
196
198class NEOGRAPH_API HostResourceLease {
199public:
200 HostResourceLease() = default;
201 HostResourceLease(const HostResourceLease&) = delete;
202 HostResourceLease& operator=(const HostResourceLease&) = delete;
203 HostResourceLease(HostResourceLease&& other) noexcept;
204 HostResourceLease& operator=(HostResourceLease&& other) noexcept;
205 ~HostResourceLease() noexcept;
206
207 [[nodiscard]] bool held() const noexcept;
208 [[nodiscard]] const HostResourceVector& resources() const noexcept;
210 [[nodiscard]] std::uint8_t priority_hint() const noexcept;
211 void release() noexcept;
212
213private:
214 friend class HostAdmissionController;
215 HostResourceLease(std::shared_ptr<detail::HostAdmissionControllerImpl> impl,
216 std::uint64_t reservation_id,
217 HostResourceVector resources) noexcept;
218
219 std::shared_ptr<detail::HostAdmissionControllerImpl> impl_;
220 std::uint64_t reservation_id_ = 0;
221 HostResourceVector resources_;
222};
231class NEOGRAPH_API HostAdmissionController {
232public:
233 explicit HostAdmissionController(HostAdmissionControllerConfig config = {});
235
237 HostAdmissionController& operator=(const HostAdmissionController&) = delete;
238
239 asio::awaitable<HostResourceLease> reserve_async(
240 HostAdmissionRequest request,
241 std::shared_ptr<graph::CancelToken> cancel_token = {});
242
244 std::optional<HostResourceLease> try_reserve(HostAdmissionRequest request);
245
246 void update_profile(HostResourceProfile profile);
251 void observe_pressure(HostPressureSample sample);
252 [[nodiscard]] HostAdmissionSnapshot snapshot() const;
253 void shutdown() noexcept;
254
255private:
256 std::shared_ptr<detail::HostAdmissionControllerImpl> impl_;
257};
258
259} // namespace neograph
NEOGRAPH_API export/import macro for shared-library builds.
Cooperative cancellation primitive for graph runs.
Shared asynchronous capacity scheduler.
void observe_pressure(HostPressureSample sample)
Apply an observed pressure state.
std::optional< HostResourceLease > try_reserve(HostAdmissionRequest request)
Non-blocking admission; never bypasses an existing waiter.
std::uint8_t priority_hint() const noexcept
Dynamic priority including a waiter that is blocked by this lease.
Immutable capacity snapshot.
static HostResourceProfile intersect(const std::vector< HostResourceProfile > &profiles, std::string profile_id)
Intersect independently enforced sources; the tightest limit wins per dimension.
HostResourceProfile scaled_available(std::uint8_t percent, std::string profile_id) const
Scale only schedulable capacity, preserving the immutable safety reserve.
static HostResourceProfile detect_current()
Detect cgroup-v2 / process limits on Linux and return conservative, bounded fallbacks elsewhere.
One atomic request to hold a vector of local host resources.
Provenance pinned with a profile so later scheduling decisions are auditable.
Construction input for an immutable local host resource profile.
HostResourceVector safety_reserve
Never admitted. It reserves host headroom for the operating system and recovery.
std::string profile_id
Host-controlled generation token; it changes whenever configured limits change.
Vector of independently reserved host resources.
static HostResourceVector saturating_add(const HostResourceVector &lhs, const HostResourceVector &rhs) noexcept
Saturating addition prevents an impossible request from wrapping into admission.
static HostResourceVector subtract_clamped(const HostResourceVector &lhs, const HostResourceVector &rhs) noexcept
Clamped subtraction is used only to expose an available diagnostic snapshot.
bool fits_within(const HostResourceVector &limit) const noexcept
True only when every requested component is at most the corresponding limit.