morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
morph::journal::SessionLog Class Reference

Full-fidelity, in-memory log of one model instance's executed actions. More...

#include <journal.hpp>

Inheritance diagram for morph::journal::SessionLog:
morph::journal::IActionLog

Public Member Functions

 SessionLog (::morph::exec::IExecutor &owner)
 Constructs an empty session log belonging to owner.
void append (LogEntry entry) override
 Appends entry, assigning a monotonically increasing seq, on the owner.
void flush () override
 No-op — checkpoint() is this class's real commit point. Callable anywhere.
std::vector< LogEntry > entries (std::string_view entityKey={}) const override
 Returns the full history (or one entity's slice of it) in append order. On the owner.
::morph::exec::IExecutor * owner () const noexcept override
 The executor given at construction.
std::unique_ptr<::morph::model::detail::IModelHolder > undoLast (std::string_view modelTypeId, ::morph::model::detail::ModelRegistryFactory &registry=::morph::model::detail::defaultRegistry(), ::morph::model::detail::ActionDispatcher &dispatcher=::morph::model::detail::defaultDispatcher())
 Drops the most recently appended entry and replays everything that remains against a fresh model instance, reconstructing the state the model was in immediately before that entry executed. On the owner.
void checkpoint (IActionLog &durableSink, ::morph::model::detail::ActionDispatcher &dispatcher=::morph::model::detail::defaultDispatcher())
 Coalesces entries appended since the last checkpoint and forwards the reduced set, in order, to durableSink; then flushes it. On the owner.
::morph::async::Completion< std::vector< LogEntry > > entries (::morph::exec::IExecutor &replyExec, std::string entityKey={}) const
 Returns recorded entries in append order, read on the log's owner and delivered on replyExec.
::morph::async::Completion< bool > flush (::morph::exec::IExecutor &replyExec)
 Pushes buffered entries to the durable backend on the log's owner; the answer is delivered on replyExec.
Public Member Functions inherited from morph::journal::IActionLog
::morph::async::Completion< std::vector< LogEntry > > entries (::morph::exec::IExecutor &replyExec, std::string entityKey={}) const
 Returns recorded entries in append order, read on the log's owner and delivered on replyExec.
::morph::async::Completion< bool > flush (::morph::exec::IExecutor &replyExec)
 Pushes buffered entries to the durable backend on the log's owner; the answer is delivered on replyExec.

Protected Member Functions

::morph::async::Completion< std::vector< LogEntry > > askEntries (::morph::exec::IExecutor &replyExec, std::string entityKey) const override
 Reads the history on the owner, delivered on replyExec.
Protected Member Functions inherited from morph::journal::IActionLog
virtual ::morph::async::Completion< bool > askFlush (::morph::exec::IExecutor &replyExec)
 What flush(replyExec) asks. The default flushes where it is called, for an implementation with no owner; one with an owner flushes there.

Detailed Description

Full-fidelity, in-memory log of one model instance's executed actions.

Attach directly via IModelHolder::attachActionLog — every successfully executed loggable action is appended here in order, regardless of any ActionLogPolicy::coalesce setting. This full history is the raw material for undoLast(). checkpoint() is the one place coalescing actually happens: entries accumulated since the last checkpoint are reduced by (modelType, entityKey, actionType) — keeping only the latest occurrence where the action's policy says coalesce == true, keeping every occurrence otherwise — and only that reduced set reaches the durable sink.

One owner
The history and the checkpoint watermark belong to the executor given at construction, which must run one task at a time. append() runs there — at once when called on it, posted from a model's strand. entries(), undoLast() and checkpoint() run only there; a caller elsewhere reads through entries(replyExec, entityKey). Because a checkpoint and every append are tasks of the one owner, a checkpoint's slice-and-forward is never interleaved with an append or with another checkpoint. See docs/spec/journal/journal.md, "One owner".

Definition at line 338 of file journal.hpp.

Constructor & Destructor Documentation

◆ SessionLog()

morph::journal::SessionLog::SessionLog ( ::morph::exec::IExecutor & owner)
inlineexplicit

Constructs an empty session log belonging to owner.

Parameters
ownerThe executor every access runs on; must run one task at a time. Borrowed: it must outlive this log and run what it posts.

Definition at line 346 of file journal.hpp.

Member Function Documentation

◆ append()

void morph::journal::SessionLog::append ( LogEntry entry)
inlineoverridevirtual

Appends entry, assigning a monotonically increasing seq, on the owner.

Always full fidelity: this is what undoLast() walks back through, so nothing is coalesced or dropped here.

Parameters
entryEntry to append; seq is overwritten regardless of the input value.

Implements morph::journal::IActionLog.

Definition at line 355 of file journal.hpp.

◆ flush() [1/2]

void morph::journal::SessionLog::flush ( )
inlineoverridevirtual

No-op — checkpoint() is this class's real commit point. Callable anywhere.

Implements morph::journal::IActionLog.

Definition at line 363 of file journal.hpp.

◆ entries() [1/2]

std::vector< LogEntry > morph::journal::SessionLog::entries ( std::string_view entityKey = {}) const
inlinenodiscardoverridevirtual

Returns the full history (or one entity's slice of it) in append order. On the owner.

Parameters
entityKeyIf non-empty, restricts the result to that entity's entries.
Returns
Matching entries, in append order.

Implements morph::journal::IActionLog.

Definition at line 369 of file journal.hpp.

◆ owner()

::morph::exec::IExecutor * morph::journal::SessionLog::owner ( ) const
inlinenodiscardoverridevirtualnoexcept

The executor given at construction.

Returns
The owner.

Reimplemented from morph::journal::IActionLog.

Definition at line 375 of file journal.hpp.

◆ undoLast()

std::unique_ptr<::morph::model::detail::IModelHolder > morph::journal::SessionLog::undoLast ( std::string_view modelTypeId,
::morph::model::detail::ModelRegistryFactory & registry = ::morph::model::detail::defaultRegistry(),
::morph::model::detail::ActionDispatcher & dispatcher = ::morph::model::detail::defaultDispatcher() )
inline

Drops the most recently appended entry and replays everything that remains against a fresh model instance, reconstructing the state the model was in immediately before that entry executed. On the owner.

No inverse/undo operations are needed on the action types themselves — this reuses replay() over a shorter prefix of the same log. A no-op (returns a freshly created, un-replayed holder) if the log is empty.

Undo only rewinds this in-memory history; it never moves the checkpoint watermark, which is keyed by entry seq (see checkpoint()). Undoing an entry a prior checkpoint() already forwarded does not un-forward it: the durable sink is append-only, so that entry stays durable while the reconstructed history diverges from it. A later checkpoint() never re-forwards a coalesced-away, already-committed entry. Applications that need to durably reverse a checkpointed action must record a compensating action, not rely on undoLast().

Replays through replay() with its default payload-schema settings. That gate cannot fire here in practice: the entries being replayed were appended by this same process, so their fingerprints are this build's by construction. Undo is not a cross-version path.

Synchronous: it returns the reconstructed holder, and its caller — the application — is the owner.

Parameters
modelTypeIdString type-id of the model to reconstruct.
registryModel factory registry; defaults to the process-level singleton.
dispatcherAction dispatcher; defaults to the process-level singleton.
Returns
A freshly created holder with the pre-undo state replayed onto it.

Definition at line 406 of file journal.hpp.

◆ checkpoint()

void morph::journal::SessionLog::checkpoint ( IActionLog & durableSink,
::morph::model::detail::ActionDispatcher & dispatcher = ::morph::model::detail::defaultDispatcher() )
inline

Coalesces entries appended since the last checkpoint and forwards the reduced set, in order, to durableSink; then flushes it. On the owner.

Advances the checkpoint watermark (the seq of the last committed entry) before forwarding, so the batch is consumed even if durableSink's append() or flush() throws: a checkpoint is a forward-only commit point (at-most-once), not a transaction to retry. A no-op if nothing has been appended since the last checkpoint.

Ordering
The whole body is one task of the owner, where every append() runs too, so no append lands between taking the slice and forwarding it, and two checkpoints forward their batches in the order they ran. That is the append-order identity the sink relies on.
Parameters
durableSinkReceives only the coalesced entries — never the raw stream. Driven from this log's owner, so it must share it: its flush() answers only on its own owner.
dispatcherSupplies each action's coalesce policy; defaults to the process-level singleton (the same one actions were registered against via BRIDGE_REGISTER_ACTION).

Definition at line 443 of file journal.hpp.

◆ askEntries()

::morph::async::Completion< std::vector< LogEntry > > morph::journal::SessionLog::askEntries ( ::morph::exec::IExecutor & replyExec,
std::string entityKey ) const
inlinenodiscardoverrideprotectedvirtual

Reads the history on the owner, delivered on replyExec.

Parameters
replyExecWhere the answer is delivered.
entityKeyIf non-empty, restricts the result to that entity's entries.
Returns
The matching entries.

Reimplemented from morph::journal::IActionLog.

Definition at line 473 of file journal.hpp.

◆ entries() [2/2]

::morph::async::Completion< std::vector< LogEntry > > morph::journal::IActionLog::entries ( ::morph::exec::IExecutor & replyExec,
std::string entityKey = {} ) const
inlinenodiscard

Returns recorded entries in append order, read on the log's owner and delivered on replyExec.

The form for a caller that is not on the owner: a model's strand, an application thread the log does not belong to. The read is ordered after every append() posted to the owner before it.

Parameters
replyExecWhere the answer is delivered, and where the caller attaches to it. Borrowed: it must outlive the completion.
entityKeyIf non-empty, restricts the result to that entity's entries.
Returns
The matching entries, in append order.

Definition at line 231 of file action_log.hpp.

◆ flush() [2/2]

Pushes buffered entries to the durable backend on the log's owner; the answer is delivered on replyExec.

The form of flush() for a caller that is not on the owner. It is ordered after every append() posted to the owner before it.

Parameters
replyExecWhere the answer is delivered. Borrowed: it must outlive the completion.
Returns
true once the entries are durable; rejected with the error flush() would have thrown.

Definition at line 245 of file action_log.hpp.


The documentation for this class was generated from the following file: