NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
Loading...
Searching...
No Matches
tenant.h
Go to the documentation of this file.
1
10#pragma once
11
12#include <neograph/api.h>
15
16#include <atomic>
17#include <cstdint>
18#include <limits>
19#include <memory>
20#include <mutex>
21#include <optional>
22#include <stdexcept>
23#include <string>
24#include <string_view>
25#include <vector>
26
27namespace neograph::tenant {
28
30class NEOGRAPH_API TenantScope final {
31public:
33 TenantScope(std::string tenant_id, std::string authorization_scope);
34
35 const std::string& tenant_id() const noexcept { return tenant_id_; }
36 const std::string& authorization_scope() const noexcept { return authorization_scope_; }
37
39 bool authorizes(std::string_view tenant_id, std::string_view authorization_scope) const noexcept;
40
41private:
42 std::string tenant_id_;
43 std::string authorization_scope_;
44};
45
47struct NEOGRAPH_API TenantQuotas {
48 std::uint64_t max_concurrency = 0;
49 std::uint64_t max_queue = 0;
50 std::uint64_t max_model_tokens = 0;
51 std::uint64_t max_cost_microunits = 0;
52 std::uint64_t max_artifacts = 0;
53 std::uint64_t max_retained_artifacts = 0;
54};
55
56class NEOGRAPH_API TenantQuotaExceeded final : public std::runtime_error {
57public:
58 explicit TenantQuotaExceeded(const char* resource);
59};
60
65class NEOGRAPH_API TenantQuota final {
66public:
67 explicit TenantQuota(TenantQuotas limits = {});
68 TenantQuota(const TenantQuota&) = delete;
69 TenantQuota& operator=(const TenantQuota&) = delete;
70
71 const TenantQuotas& limits() const noexcept { return limits_; }
72 std::uint64_t active() const noexcept;
73 std::uint64_t queued() const noexcept;
74 std::uint64_t model_tokens() const noexcept;
75 std::uint64_t cost_microunits() const noexcept;
76 std::uint64_t artifacts() const noexcept;
77 std::uint64_t retained_artifacts() const noexcept;
78
80 bool try_acquire_concurrency() noexcept;
81 void release_concurrency() noexcept;
83 bool try_acquire_queue() noexcept;
84 void release_queue() noexcept;
86 bool try_reserve_usage(std::uint64_t model_tokens,
87 std::uint64_t cost_microunits) noexcept;
89 void release_usage(std::uint64_t model_tokens,
90 std::uint64_t cost_microunits) noexcept;
91 bool try_acquire_artifact() noexcept;
92 void release_artifact() noexcept;
93 bool try_acquire_retained_artifact() noexcept;
94 void release_retained_artifact() noexcept;
95
96private:
97 bool try_increment(std::atomic<std::uint64_t>& value, std::uint64_t limit) noexcept;
98 static void decrement(std::atomic<std::uint64_t>& value, std::uint64_t amount) noexcept;
99
100 const TenantQuotas limits_;
101 std::atomic<std::uint64_t> active_{0};
102 std::atomic<std::uint64_t> queued_{0};
103 std::atomic<std::uint64_t> model_tokens_{0};
104 std::atomic<std::uint64_t> cost_microunits_{0};
105 std::atomic<std::uint64_t> artifacts_{0};
106 std::atomic<std::uint64_t> retained_artifacts_{0};
107};
108
110class NEOGRAPH_API TenantQuotaLease final {
111public:
112 TenantQuotaLease() noexcept = default;
113 static TenantQuotaLease acquire(TenantQuota& quota, bool artifact = false);
114 TenantQuotaLease(TenantQuotaLease&& other) noexcept;
115 TenantQuotaLease& operator=(TenantQuotaLease&& other) noexcept;
116 TenantQuotaLease(const TenantQuotaLease&) = delete;
117 TenantQuotaLease& operator=(const TenantQuotaLease&) = delete;
119 void release() noexcept;
120 explicit operator bool() const noexcept { return quota_ != nullptr; }
121
122private:
123 TenantQuotaLease(TenantQuota* quota, bool artifact) noexcept
124 : quota_(quota), artifact_(artifact) {}
125 TenantQuota* quota_ = nullptr;
126 bool artifact_ = false;
127};
128
134class NEOGRAPH_API ScopedStore final : public graph::Store {
135public:
136 ScopedStore(TenantScope scope, std::shared_ptr<graph::Store> backend);
137 const TenantScope& scope() const noexcept { return scope_; }
138
139 void put(const graph::Namespace& ns, const std::string& key,
140 const json& value) override;
141 std::optional<graph::StoreItem> get(const graph::Namespace& ns,
142 const std::string& key) const override;
143 std::vector<graph::StoreItem> search(const graph::Namespace& ns_prefix,
144 int limit = 100) const override;
145 void delete_item(const graph::Namespace& ns, const std::string& key) override;
146 std::vector<graph::Namespace>
147 list_namespaces(const graph::Namespace& prefix = {}) const override;
148
149private:
150 graph::Namespace private_namespace(const graph::Namespace& ns) const;
151 graph::StoreItem public_item(graph::StoreItem item) const;
152 TenantScope scope_;
153 std::shared_ptr<graph::Store> backend_;
154};
155
157class NEOGRAPH_API ScopedCheckpointStore final : public graph::CheckpointStore {
158public:
159 ScopedCheckpointStore(TenantScope scope, std::shared_ptr<graph::CheckpointStore> backend);
160 const TenantScope& scope() const noexcept { return scope_; }
161
162 void save(const graph::Checkpoint& cp) override;
163 std::optional<graph::Checkpoint> load_latest(const std::string& thread_id) override;
164 std::optional<graph::Checkpoint> load_by_id(const std::string& id) override;
165 std::vector<graph::Checkpoint> list(const std::string& thread_id,
166 int limit = 100) override;
167 void delete_thread(const std::string& thread_id) override;
168 void put_writes(const std::string& thread_id, const std::string& parent_checkpoint_id,
169 const graph::PendingWrite& write) override;
170 std::vector<graph::PendingWrite>
171 get_writes(const std::string& thread_id, const std::string& parent_checkpoint_id) override;
172 void clear_writes(const std::string& thread_id,
173 const std::string& parent_checkpoint_id) override;
174 bool requires_managed_budget(const std::string& thread_id) override;
175 asio::awaitable<bool> requires_managed_budget_async(std::string thread_id) override;
176 std::shared_ptr<graph::OwnedManagedBudgetLease> acquire_managed_budget_lease(
177 const graph::ManagedBudgetLeaseScope& scope, const std::string& expected_checkpoint_id,
178 const std::string& expected_checkpoint_commitment) override;
179 asio::awaitable<std::shared_ptr<graph::OwnedManagedBudgetLease>>
180 acquire_managed_budget_lease_async(graph::ManagedBudgetLeaseScope scope,
181 std::string expected_checkpoint_id, std::string expected_checkpoint_commitment) override;
182 graph::ManagedBudgetEffectReceipt begin_managed_budget_effect(
183 const std::shared_ptr<graph::OwnedManagedBudgetLease>& lease, const std::string& effect_id,
184 std::uint64_t exact_claim_amount, const std::string& prepared_request_digest) override;
185 asio::awaitable<graph::ManagedBudgetEffectReceipt> begin_managed_budget_effect_async(
186 std::shared_ptr<graph::OwnedManagedBudgetLease> lease, std::string effect_id,
187 std::uint64_t exact_claim_amount, std::string prepared_request_digest) override;
188 void settle_managed_budget_effect(const std::shared_ptr<graph::OwnedManagedBudgetLease>& lease,
189 const graph::ManagedBudgetEffectReceipt& effect, sp::runtime::Result genuine_outcome,
190 const UsageAccumulator::AuthoritySnapshot& authority) override;
191 asio::awaitable<void> settle_managed_budget_effect_async(
192 std::shared_ptr<graph::OwnedManagedBudgetLease> lease,
193 graph::ManagedBudgetEffectReceipt effect, sp::runtime::Result genuine_outcome,
194 UsageAccumulator::AuthoritySnapshot authority) override;
195 void publish_managed_budget_checkpoint(
196 const std::shared_ptr<graph::OwnedManagedBudgetLease>& lease,
197 const graph::Checkpoint& checkpoint) override;
198 asio::awaitable<void> publish_managed_budget_checkpoint_async(
199 std::shared_ptr<graph::OwnedManagedBudgetLease> lease, graph::Checkpoint checkpoint) override;
200 void release_managed_budget_lease(
201 const std::shared_ptr<graph::OwnedManagedBudgetLease>& lease) override;
202 asio::awaitable<void> release_managed_budget_lease_async(
203 std::shared_ptr<graph::OwnedManagedBudgetLease> lease) override;
204 bool retains_native_checkpoint() const noexcept override;
205 void publish_managed_budget_fork(const graph::Checkpoint& authenticated_source,
206 const graph::Checkpoint& genuine_shared_bank_fork) override;
207 asio::awaitable<void> publish_managed_budget_fork_async(
208 graph::Checkpoint source, graph::Checkpoint forked) override;
209
210private:
211 std::string private_id(std::string_view id) const;
212 graph::Checkpoint private_checkpoint(const graph::Checkpoint& cp) const;
213 graph::Checkpoint public_checkpoint(graph::Checkpoint cp) const;
214 graph::ManagedBudgetLeaseScope private_scope(graph::ManagedBudgetLeaseScope scope) const;
215 std::string private_source_commitment(
216 const graph::Checkpoint& checkpoint, const std::string& expected_checkpoint_id,
217 const std::string& expected_checkpoint_commitment) const;
218 TenantScope scope_;
219 std::shared_ptr<graph::CheckpointStore> backend_;
220};
221
222} // namespace neograph::tenant
223
224namespace neograph::graph {
229using TenantQuotaExceeded = tenant::TenantQuotaExceeded;
232} // namespace neograph::graph
NEOGRAPH_API export/import macro for shared-library builds.
Checkpoint system for graph execution state persistence and time-travel.
Abstract interface for checkpoint persistence backends.
Definition checkpoint.h:400
Actual write-ahead claim, bound to one original generation and owned actor.
Definition checkpoint.h:96
Abstract interface for cross-thread shared memory.
Definition store.h:49
Checkpoint namespace owned by one trusted tenant.
Definition tenant.h:157
void clear_writes(const std::string &thread_id, const std::string &parent_checkpoint_id) override
Discard pending writes for a parent checkpoint once its successor super-step has been fully committed...
std::optional< graph::Checkpoint > load_by_id(const std::string &id) override
Load a checkpoint by its unique ID.
void delete_thread(const std::string &thread_id) override
Delete all checkpoints for a thread.
void put_writes(const std::string &thread_id, const std::string &parent_checkpoint_id, const graph::PendingWrite &write) override
Record a successful node execution within an in-progress super-step.
std::optional< graph::Checkpoint > load_latest(const std::string &thread_id) override
Load the most recently saved checkpoint for a thread.
void save(const graph::Checkpoint &cp) override
Save a checkpoint.
std::vector< graph::PendingWrite > get_writes(const std::string &thread_id, const std::string &parent_checkpoint_id) override
Load all pending writes attached to a parent checkpoint.
std::vector< graph::Checkpoint > list(const std::string &thread_id, int limit=100) override
List checkpoints for a thread, most recently saved first, one entry per ID; the first entry is load_l...
bool retains_native_checkpoint() const noexcept override
Describes real local C++ custody, not a financial admission/grant.
bool requires_managed_budget(const std::string &thread_id) override
Whether this trusted checkpoint namespace/thread has ever held an active standalone managed bank.
Store namespace owned by one trusted tenant.
Definition tenant.h:134
std::optional< graph::StoreItem > get(const graph::Namespace &ns, const std::string &key) const override
Retrieve a single item.
std::vector< graph::Namespace > list_namespaces(const graph::Namespace &prefix={}) const override
List all namespaces under a prefix.
void put(const graph::Namespace &ns, const std::string &key, const json &value) override
Store a value (create or update).
std::vector< graph::StoreItem > search(const graph::Namespace &ns_prefix, int limit=100) const override
Search items under a namespace prefix.
void delete_item(const graph::Namespace &ns, const std::string &key) override
Delete a single item.
Move-only RAII reservation for a request and its optional artifact.
Definition tenant.h:110
Thread-safe quota ledger.
Definition tenant.h:65
bool try_acquire_concurrency() noexcept
Reserve one running slot.
Immutable identity and authorization binding supplied by trusted ingress.
Definition tenant.h:30
TenantScope(std::string tenant_id, std::string authorization_scope)
Construct only from already-authenticated, non-secret logical IDs.
bool authorizes(std::string_view tenant_id, std::string_view authorization_scope) const noexcept
Exact-match check used by an ingress adapter before dispatch.
Cross-thread shared memory store (LangGraph Store equivalent).
std::vector< std::string > Namespace
Hierarchical namespace path for store items.
Definition store.h:28
Serialized snapshot of graph execution state at a single super-step.
Definition checkpoint.h:173
Successful node writes recorded within an in-progress super-step.
Definition checkpoint.h:242
A single item stored in the cross-thread Store.
Definition store.h:33
Per-tenant admission and retention limits.
Definition tenant.h:47