|
morph 0.1.0
Asynchronous bridge between GUI thread and business models
|
Interface for an op-id-keyed exactly-once replay ledger. More...
#include <replay_ledger.hpp>
Public Member Functions | |
| 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. | |
| ::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 delivered on replyExec. | |
Protected Member Functions | |
| 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, for an implementation with no owner; one with an owner looks up there. | |
| virtual std::optional< std::string > | doLookup (std::string_view scope, std::string_view opId) const =0 |
| Storage hook for lookup(). | |
| 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/ already recorded (first-write-wins). | |
Interface for an op-id-keyed exactly-once replay ledger.
Answers one question — "has this operation id already been applied?" — for a host that must dedup a retried write against one it already committed. One framework seam in place of a near-identical table each host would otherwise hand-write. A host either stores a result and replays it verbatim on a hit ("response-replay"), or stores nothing and reports only that the op was seen ("skip-only", as examples/bookmarks' import path does). Both are the same mechanism with a different caller-side interpretation of the stored payload — see lookup()'s own doc comment — so there is exactly one interface here, not two.
Definition at line 47 of file replay_ledger.hpp.
|
inlinenodiscard |
Reports whether opId within scope has already been decided.
| scope | Caller-chosen partition; empty is a valid, distinct scope. |
| opId | The operation id to look up. Empty always reports std::nullopt, regardless of what has been recorded. |
opId (possibly empty, for a skip-only caller), or std::nullopt if it has not been recorded — or opId is empty. Definition at line 82 of file replay_ledger.hpp.
|
inline |
Records that opId within scope has been decided, with payload attached.
opId within scope that is already decided is a no-op — the existing payload is kept, payload here is discarded, and no error is raised. This is the same contract morph::journal::IActionLog::append()'s idempotency-key dedup already ships (journal/action_log.hpp's own doc comment: "if an entry with
the same key was already recorded, treat the call as a no-op"): a redelivered retry that reaches record() a second time (e.g. because a reply was lost after the first commit) must not overwrite a payload a caller may already have replayed to someone else.| scope | Caller-chosen partition; must match the scope a later lookup() uses to find this entry. |
| opId | The operation id being recorded. A no-op if empty. |
| payload | Opaque payload to associate with opId; empty for a skip-only caller that only cares whether a hit occurred. |
Definition at line 126 of file replay_ledger.hpp.
|
inlinenodiscard |
Reports whether opId within scope has already been decided, looked up on the ledger's owner and delivered on replyExec.
The form of lookup() for a caller that is not on the ledger's owner. A lookup answered elsewhere cannot be atomic with the record() that follows it; a caller that needs check-then-set atomicity runs both on the owner.
| replyExec | Where the answer is delivered, and where the caller attaches to it. Borrowed: it must outlive the completion. |
| scope | Caller-chosen partition; empty is a valid, distinct scope. |
| opId | The operation id to look up. Empty always answers std::nullopt. |
Definition at line 148 of file replay_ledger.hpp.
|
inlinenodiscardprotectedvirtual |
What lookup(replyExec, scope, opId) asks. The default looks up where it is called, for an implementation with no owner; one with an owner looks up there.
| replyExec | Where the answer is delivered. |
| scope | Caller-chosen partition. |
| opId | The operation id to look up; never empty here. |
opId, or std::nullopt. Reimplemented in morph::offline::InMemoryReplayLedger.
Definition at line 167 of file replay_ledger.hpp.
|
nodiscardprotectedpure virtual |
Storage hook for lookup().
| scope | Caller-chosen partition, forwarded verbatim from lookup(). |
| opId | The operation id to look up; never empty here – the public wrapper already handled that case. |
opId, or std::nullopt if none. Implemented in morph::offline::InMemoryReplayLedger.
|
protectedpure virtual |
Storage hook for record(). Must be a no-op if scope/ already recorded (first-write-wins). opId is
| scope | Caller-chosen partition, forwarded verbatim from record(). |
| opId | The operation id being recorded; never empty here – the public wrapper already handled that case. |
| payload | Opaque payload to associate with opId. |
Implemented in morph::offline::InMemoryReplayLedger.