14#include <asio/awaitable.hpp>
24namespace neograph::program {
27 ProgramActivation activation;
28 ProgramVersion version;
47 const ProgramBundle& bundle,
48 const ProgramVersion& version) = 0;
49 [[nodiscard]]
virtual asio::awaitable<std::optional<ProgramBundle>> get_bundle(std::string_view
id)
const = 0;
50 [[nodiscard]]
virtual asio::awaitable<std::optional<ProgramVersion>> get_version(std::string_view
id)
const = 0;
58 [[nodiscard]]
virtual asio::awaitable<std::optional<ProgramBundle>>
get_bundle(
60 std::string_view )
const {
61 co_return std::nullopt;
63 [[nodiscard]]
virtual asio::awaitable<std::optional<ProgramVersion>> get_version(
64 std::string_view owner_scope,
65 std::string_view
id)
const {
66 if (owner_scope.empty())
co_return std::nullopt;
67 const auto value =
co_await get_version(
id);
68 if (!value || value->ownership_scope() != owner_scope)
co_return std::nullopt;
78 [[nodiscard]]
virtual asio::awaitable<std::optional<ProgramActivation>>
get_activation(
79 std::string_view )
const {
80 return detail::failed_store_call<std::optional<ProgramActivation>>(
81 std::make_exception_ptr(std::logic_error(
"ProgramStore does not expose activation lifecycle")));
88 [[nodiscard]]
virtual asio::awaitable<std::optional<ProgramActivationBinding>>
get_active_binding(
89 std::string_view owner_scope)
const {
90 const auto active =
co_await get_activation(owner_scope);
91 if (!active)
co_return std::nullopt;
92 const auto version =
co_await get_version(owner_scope, active->active_version_id());
93 if (!version || version->policy_snapshot().fingerprint() != active->policy_snapshot_hash())
94 throw std::runtime_error(
"Program activation target is missing or has a mismatched policy");
97 [[nodiscard]]
virtual asio::awaitable<ProgramActivationResult> compare_activate(
102 return detail::failed_store_call<ProgramActivationResult>(
103 std::make_exception_ptr(std::logic_error(
"ProgramStore does not expose activation lifecycle")));
105 [[nodiscard]]
virtual asio::awaitable<std::vector<ProgramVersion>> list_versions(
106 std::string_view )
const {
107 return detail::failed_store_call<std::vector<ProgramVersion>>(
108 std::make_exception_ptr(std::logic_error(
"ProgramStore does not enumerate versions")));
110 [[nodiscard]]
virtual asio::awaitable<ProgramRetentionReport> collect_garbage(
112 const std::vector<std::string>& ) {
113 return detail::failed_store_call<ProgramRetentionReport>(
114 std::make_exception_ptr(std::logic_error(
"ProgramStore does not expose retention lifecycle")));
126 virtual void publish_admitted_sync(
const ProgramBundle& bundle,
const ProgramVersion& version) = 0;
127 virtual std::optional<ProgramBundle> get_bundle_sync(std::string_view
id)
const = 0;
128 virtual std::optional<ProgramVersion> get_version_sync(std::string_view
id)
const = 0;
129 virtual std::optional<ProgramBundle> get_bundle_sync(
131 std::string_view )
const {
134 virtual std::optional<ProgramVersion> get_version_sync(
135 std::string_view owner_scope,
136 std::string_view
id)
const {
137 if (owner_scope.empty())
return std::nullopt;
138 const auto value = get_version_sync(
id);
139 if (!value || value->ownership_scope() != owner_scope)
return std::nullopt;
142 virtual std::optional<ProgramActivation> get_activation_sync(
143 std::string_view )
const {
144 throw std::logic_error(
"ProgramStore does not expose activation lifecycle");
146 virtual std::optional<ProgramActivationBinding> get_active_binding_sync(
147 std::string_view owner_scope)
const {
148 const auto active = get_activation_sync(owner_scope);
149 if (!active)
return std::nullopt;
150 const auto version = get_version_sync(owner_scope, active->active_version_id());
151 if (!version || version->policy_snapshot().fingerprint() != active->policy_snapshot_hash())
152 throw std::runtime_error(
"Program activation target is missing or has a mismatched policy");
160 throw std::logic_error(
"ProgramStore does not expose activation lifecycle");
162 virtual std::vector<ProgramVersion> list_versions_sync(
163 std::string_view )
const {
164 throw std::logic_error(
"ProgramStore does not enumerate versions");
168 const std::vector<std::string>& ) {
169 throw std::logic_error(
"ProgramStore does not expose retention lifecycle");
175 const ProgramBundle& bundle,
176 const ProgramVersion& version)
final;
177 [[nodiscard]] asio::awaitable<std::optional<ProgramBundle>> get_bundle(std::string_view
id)
const final;
178 [[nodiscard]] asio::awaitable<std::optional<ProgramVersion>> get_version(std::string_view
id)
const final;
179 [[nodiscard]] asio::awaitable<std::optional<ProgramBundle>>
get_bundle(
180 std::string_view owner_scope,
181 std::string_view
id)
const final;
182 [[nodiscard]] asio::awaitable<std::optional<ProgramVersion>> get_version(
183 std::string_view owner_scope,
184 std::string_view
id)
const final;
186 std::string_view owner_scope)
const final;
188 std::string_view owner_scope)
const final;
189 [[nodiscard]] asio::awaitable<ProgramActivationResult> compare_activate(
190 std::string_view owner_scope,
191 std::uint64_t expected_generation,
192 std::string_view version_id,
193 std::string_view policy_snapshot_hash)
final;
194 [[nodiscard]] asio::awaitable<std::vector<ProgramVersion>> list_versions(
195 std::string_view owner_scope)
const final;
196 [[nodiscard]] asio::awaitable<ProgramRetentionReport> collect_garbage(
197 std::string_view owner_scope,
198 const std::vector<std::string>& pinned_version_ids)
final;
205 virtual bool offloads() const noexcept {
return false; }
218 const std::shared_ptr<ProgramStore>& store() const noexcept {
return store_; }
220 void publish_admitted(
const ProgramBundle& bundle,
const ProgramVersion& version)
const;
221 std::optional<ProgramBundle> get_bundle(std::string_view
id)
const;
222 std::optional<ProgramVersion> get_version(std::string_view
id)
const;
223 std::optional<ProgramBundle> get_bundle(std::string_view owner_scope, std::string_view
id)
const;
224 std::optional<ProgramVersion> get_version(std::string_view owner_scope, std::string_view
id)
const;
225 std::optional<ProgramActivation> get_activation(std::string_view owner_scope)
const;
226 std::optional<ProgramActivationBinding> get_active_binding(std::string_view owner_scope)
const;
227 ProgramActivationResult compare_activate(
228 std::string_view owner_scope,
229 std::uint64_t expected_generation,
230 std::string_view version_id,
231 std::string_view policy_snapshot_hash)
const;
232 std::vector<ProgramVersion> list_versions(std::string_view owner_scope)
const;
233 ProgramRetentionReport collect_garbage(
234 std::string_view owner_scope,
235 const std::vector<std::string>& pinned_version_ids)
const;
238 std::shared_ptr<ProgramStore> store_;
239 SyncProgramStore* sync_ =
nullptr;
240 BlockingStorePolicy policy_;
243class NEOGRAPH_PROGRAM_API InMemoryProgramStore final :
public SyncProgramStore {
245 InMemoryProgramStore();
246 InMemoryProgramStore(InMemoryProgramStore&&) noexcept;
247 InMemoryProgramStore& operator=(InMemoryProgramStore&&) noexcept;
248 InMemoryProgramStore(const InMemoryProgramStore&) = delete;
249 InMemoryProgramStore& operator=(const InMemoryProgramStore&) = delete;
250 ~InMemoryProgramStore() override;
252 void publish_admitted_sync(const ProgramBundle& bundle, const ProgramVersion& version) override;
253 std::optional<ProgramBundle> get_bundle_sync(std::string_view
id) const override;
254 std::optional<ProgramVersion> get_version_sync(std::string_view
id) const override;
255 std::optional<ProgramBundle> get_bundle_sync(std::string_view owner_scope,
256 std::string_view
id) const override;
257 std::optional<ProgramVersion> get_version_sync(std::string_view owner_scope,
258 std::string_view
id) const override;
259 std::optional<ProgramActivation>
260 get_activation_sync(std::string_view owner_scope) const override;
261 std::optional<ProgramActivationBinding>
262 get_active_binding_sync(std::string_view owner_scope) const override;
263 ProgramActivationResult compare_activate_sync(std::string_view owner_scope,
264 std::uint64_t expected_generation,
265 std::string_view version_id,
266 std::string_view policy_snapshot_hash) override;
267 std::vector<ProgramVersion> list_versions_sync(std::string_view owner_scope) const override;
268 ProgramRetentionReport collect_garbage_sync(
269 std::string_view owner_scope,
270 const std::vector<std::
string>& pinned_version_ids) override;
274 std::unique_ptr<Impl> impl_;
Owner-scoped activation records for immutable Program versions.
ProgramActivationResult
Result of an atomic owner-scoped activation compare-and-swap.
NEOGRAPH_API export/import macro for shared-library builds.
Immutable, content-addressed Program compilation artifacts.
A ProgramStore for a caller that cannot suspend: the catalog and the synchronous Program API.
BlockingProgramStore(ProgramStore &store, BlockingStorePolicy policy={})
A view of a store that outlives it.
Atomic storage of admitted Program bundles and versions, as the catalog uses it (#556).
virtual asio::awaitable< std::optional< ProgramBundle > > get_bundle(std::string_view, std::string_view) const
Owner-qualified lookups.
virtual asio::awaitable< void > publish_admitted(const ProgramBundle &bundle, const ProgramVersion &version)=0
Atomically publish one admitted bundle/version tuple.
virtual asio::awaitable< std::optional< ProgramActivation > > get_activation(std::string_view) const
Owner-scoped activation lifecycle.
virtual asio::awaitable< std::optional< ProgramActivationBinding > > get_active_binding(std::string_view owner_scope) const
Return one coherent activation/version tuple.
Base of a ProgramStore whose backend is synchronous: the in-memory store, SQLite and PostgreSQL.
asio::awaitable< std::optional< ProgramBundle > > get_bundle(std::string_view owner_scope, std::string_view id) const final
Owner-qualified lookups.
asio::awaitable< std::optional< ProgramActivationBinding > > get_active_binding(std::string_view owner_scope) const final
Return one coherent activation/version tuple.
bool completes_at_once() const noexcept
True when every awaitable operation completes at once on the calling thread, not on a pool thread.
virtual bool offloads() const noexcept
True for a backend that blocks for long: each operation then runs on a pool thread.
asio::awaitable< void > publish_admitted(const ProgramBundle &bundle, const ProgramVersion &version) final
Atomically publish one admitted bundle/version tuple.
asio::awaitable< std::optional< ProgramActivation > > get_activation(std::string_view owner_scope) const final
Owner-scoped activation lifecycle.
How a Program store call is awaited, and how a synchronous caller waits for one (#556).
When a Blocking...Store may wait for a store call that does not complete at once.
Coherent owner-scoped activation pointer and its admitted immutable target.
Counts immutable records removed by reference-aware collection.
Immutable stored binding between a Program bundle and admission receipts.