12#include "../attributes.hpp"
13#include "../core/completion.hpp"
15#include "../core/executor.hpp"
17namespace morph::offline {
82 [[nodiscard]] std::optional<std::string>
lookup(std::string_view scope, std::string_view opId)
const {
126 void record(std::string_view scope, std::string_view opId, std::string payload) {
130 doRecord(scope, opId, std::move(payload));
152 settleable.second.resolve(std::nullopt);
153 return std::move(settleable.first);
155 return askLookup(replyExec, std::string{scope}, std::string{opId});
167 [[nodiscard]] virtual ::morph::async::Completion<std::optional<std::string>>
askLookup(
170 std::string scope, std::string opId)
const {
173 settleable.second.resolve(
doLookup(scope, opId));
175 settleable.second.reject(std::current_exception());
177 return std::move(settleable.first);
186 [[nodiscard]]
virtual std::optional<std::string>
doLookup(std::string_view scope, std::string_view opId)
const = 0;
195 virtual void doRecord(std::string_view scope, std::string_view opId, std::string payload) = 0;
222 : _owned{owner, std::make_shared<State>()} {}
263 [[nodiscard]] std::optional<std::string>
doLookup(std::string_view scope, std::string_view opId)
const override {
264 return find(_owned.read(
"InMemoryReplayLedger::lookup"), scope, opId);
274 void doRecord(std::string_view scope, std::string_view opId, std::string payload)
override {
275 _owned.apply(
"InMemoryReplayLedger::record", [key = Key{std::string{scope}, std::string{opId}},
276 payload = std::move(payload)](State& state)
mutable {
280 state.entries.emplace(std::move(key), std::move(payload));
292 std::string opId)
const override {
293 return _owned.ask<std::optional<std::string>>(
294 "InMemoryReplayLedger::lookup", replyExec,
295 [scope = std::move(scope), opId = std::move(opId)](State& state) {
return find(state, scope, opId); });
299 using Key = std::pair<std::string, std::string>;
303 std::map<Key, std::string> entries;
308 static std::optional<std::string> find(
const State& state, std::string_view scope, std::string_view opId) {
309 auto const iter = state.entries.find(Key{std::string{scope}, std::string{opId}});
310 if (iter == state.entries.end()) {
316 ::morph::exec::detail::OwnedState<State> _owned;
Move-only handle representing the eventual result of an asynchronous operation.
InMemoryReplayLedger(::morph::exec::IExecutor &owner)
Constructs an empty ledger belonging to owner.
void doRecord(std::string_view scope, std::string_view opId, std::string payload) override
Records opId within scope in the in-memory map, unless already present (first-write-wins)....
std::optional< std::string > doLookup(std::string_view scope, std::string_view opId) const override
Looks up opId within scope in the in-memory map. On the owner.
::morph::async::Completion< std::optional< std::string > > askLookup(::morph::exec::IExecutor &replyExec, std::string scope, std::string opId) const override
Looks up on the owner, answered on replyExec.
OwnedState: a component's state, and the one executor it is touched on.
Abstract executor interface.
Interface for an op-id-keyed exactly-once replay ledger.
::morph::async::Completion< std::optional< std::string > > lookup(::morph::exec::IExecutor &replyExec, std::string_view scope, std::string_view opId) const
Reports whether opId within scope has already been decided, looked up on the ledger's owner and deliv...
virtual ::morph::async::Completion< std::optional< std::string > > askLookup(::morph::exec::IExecutor &replyExec, std::string scope, std::string opId) const
What lookup(replyExec, scope, opId) asks. The default looks up where it is called,...
virtual void doRecord(std::string_view scope, std::string_view opId, std::string payload)=0
Storage hook for record(). Must be a no-op if scope/opId is already recorded (first-write-wins).
virtual std::optional< std::string > doLookup(std::string_view scope, std::string_view opId) const =0
Storage hook for lookup().
std::optional< std::string > lookup(std::string_view scope, std::string_view opId) const
Reports whether opId within scope has already been decided.
void record(std::string_view scope, std::string_view opId, std::string payload)
Records that opId within scope has been decided, with payload attached.