|
morph 0.1.0
Asynchronous bridge between GUI thread and business models
|
Reference append-only, NDJSON-backed IOfflineQueue that persists payload, idempotencyKey, and attempts across process restarts with no third-party dependency. More...
#include <file_offline_queue.hpp>
Public Member Functions | |
| FileOfflineQueue (::morph::exec::IExecutor &owner, std::filesystem::path path, ::morph::core::FileIoOps ioOps={}, std::optional< std::size_t > maxDepth=std::nullopt) | |
Opens (or creates) the queue log at path, replaying and compacting whatever is already there; the queue belongs to owner. | |
| FileOfflineQueue (const FileOfflineQueue &)=delete | |
| FileOfflineQueue & | operator= (const FileOfflineQueue &)=delete |
| FileOfflineQueue (FileOfflineQueue &&)=delete | |
| FileOfflineQueue & | operator= (FileOfflineQueue &&)=delete |
| uint64_t | enqueue (std::string payload) override |
Appends payload with no idempotency key. On the owner. | |
| uint64_t | enqueue (std::string payload, std::string idempotencyKey) override |
Appends payload carrying idempotencyKey. On the owner. A non-empty key already present on a pending item is deduplicated: the existing item's id is returned and nothing new is written. | |
| std::vector< QueueItem > | drain () const override |
| Returns all pending items in ascending-id (enqueue) order. On the owner. | |
| std::size_t | size () const override |
| Returns the number of pending items. On the owner. | |
| std::optional< std::size_t > | maxDepth () const override |
| Returns the configured maximum depth, or std::nullopt if unbounded. Callable anywhere: fixed at construction. | |
| void | markDone (uint64_t itemId) override |
Tombstones itemId, on the owner. No-op if not found. | |
| void | setAttempts (uint64_t itemId, Attempts attempts) override |
Persists an updated attempt count for itemId, on the owner. No-op if not found. | |
| ::morph::async::Completion< std::vector< QueueItem > > | drain (::morph::exec::IExecutor &replyExec) const |
Snapshots the pending items on the queue's owner; delivered on replyExec. | |
| ::morph::async::Completion< uint64_t > | enqueue (::morph::exec::IExecutor &replyExec, std::string payload, std::string idempotencyKey={}) |
Appends payload carrying idempotencyKey on the queue's owner; the new item's id is delivered on replyExec. | |
| ::morph::async::Completion< std::size_t > | size (::morph::exec::IExecutor &replyExec) const |
Counts the pending items on the queue's owner; delivered on replyExec. | |
| Public Member Functions inherited from morph::offline::IOfflineQueue | |
| ::morph::async::Completion< uint64_t > | enqueue (::morph::exec::IExecutor &replyExec, std::string payload, std::string idempotencyKey={}) |
Appends payload carrying idempotencyKey on the queue's owner; the new item's id is delivered on replyExec. | |
| ::morph::async::Completion< std::vector< QueueItem > > | drain (::morph::exec::IExecutor &replyExec) const |
Snapshots the pending items on the queue's owner; delivered on replyExec. | |
| ::morph::async::Completion< std::size_t > | size (::morph::exec::IExecutor &replyExec) const |
Counts the pending items on the queue's owner; delivered on replyExec. | |
Protected Member Functions | |
| void | setIdempotencyKey (uint64_t itemId, std::string idempotencyKey) override |
Stamps an idempotency key onto an already-enqueued item, on the owner. No-op if itemId is not found. Reachable only if a caller invokes the base IOfflineQueue::enqueue(payload, key) default through an IOfflineQueue& — this class's own enqueue(payload, key) override above stamps the key inline instead. | |
| ::morph::async::Completion< uint64_t > | askEnqueue (::morph::exec::IExecutor &replyExec, std::string payload, std::string idempotencyKey) override |
Enqueues on the owner, answered on replyExec. | |
| ::morph::async::Completion< std::vector< QueueItem > > | askDrain (::morph::exec::IExecutor &replyExec) const override |
Snapshots on the owner, answered on replyExec. | |
| ::morph::async::Completion< std::size_t > | askSize (::morph::exec::IExecutor &replyExec) const override |
Counts on the owner, answered on replyExec. | |
Reference append-only, NDJSON-backed IOfflineQueue that persists payload, idempotencyKey, and attempts across process restarts with no third-party dependency.
Each mutation (enqueue, markDone, setAttempts, setIdempotencyKey) appends one JSON line and immediately fflush+fsyncs it, so it is a committed transaction before the call returns. On construction, the file is replayed line by line (last-write-wins per id — a later "put" overwrites an earlier one, a "done" tombstones it) and then rewritten in compacted form (one "put" line per surviving item), which both bounds file growth and heals a torn trailing line left by a crash mid-write — the same tolerance FileActionLog::entries() (include/morph/journal/file_action_log.hpp) gives a malformed trailing line: it is logged and skipped, not thrown: a malformed line anywhere else is genuine corruption and is rethrown.
New ids resume from the highest id ever seen in the file (including tombstoned ones), so a fresh item can never collide with an old tombstone — unlike FileActionLog's process-local seq, which does not need this property because it never reuses/removes entries.
Definition at line 146 of file file_offline_queue.hpp.
|
inline |
Opens (or creates) the queue log at path, replaying and compacting whatever is already there; the queue belongs to owner.
Runs on the constructing thread, before anything else can reach the queue.
| owner | The executor every access runs on; must run one task at a time. Borrowed: it must outlive this queue and run what it posts. |
| path | NDJSON file to store queue state in. |
| ioOps | Injectable file-I/O primitives; defaults to the real syscalls. Test-only seam — see morph::core::FileIoOps's own docs — for forcing the failure branches that need a real OS-level I/O error to reach. |
| maxDepth | Maximum number of pending items enqueue() will admit before throwing OfflineQueueFullError; std::nullopt (the default) means unbounded. Not persisted in the file itself — a per-construction parameter, so a reopen must pass it again to keep the same cap enforced. |
| FileOfflineQueueError | if path exists but contains a malformed non-trailing line. |
| std::runtime_error | if path cannot be opened/rewritten. |
Definition at line 171 of file file_offline_queue.hpp.
|
inlinenodiscardoverridevirtual |
Appends payload with no idempotency key. On the owner.
| payload | Serialised action to persist. |
Implements morph::offline::IOfflineQueue.
Definition at line 185 of file file_offline_queue.hpp.
|
inlinenodiscardoverridevirtual |
Appends payload carrying idempotencyKey. On the owner. A non-empty key already present on a pending item is deduplicated: the existing item's id is returned and nothing new is written.
| payload | Serialised action to persist. |
| idempotencyKey | Stable dedup token; empty means "no dedup". |
| OfflineQueueFullError | if the queue is already at maxDepth() (a dedup hit above bypasses this check and always succeeds). |
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 196 of file file_offline_queue.hpp.
|
inlinenodiscardoverridevirtual |
Returns all pending items in ascending-id (enqueue) order. On the owner.
Implements morph::offline::IOfflineQueue.
Definition at line 203 of file file_offline_queue.hpp.
|
inlinenodiscardoverridevirtual |
Returns the number of pending items. On the owner.
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 209 of file file_offline_queue.hpp.
|
inlinenodiscardoverridevirtual |
Returns the configured maximum depth, or std::nullopt if unbounded. Callable anywhere: fixed at construction.
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 214 of file file_offline_queue.hpp.
|
inlineoverridevirtual |
Tombstones itemId, on the owner. No-op if not found.
Called off the owner, the tombstone is posted there and this returns at once; a write that fails there is logged, and the item stays queued.
| itemId | Id returned by the corresponding enqueue() call. |
Implements morph::offline::IOfflineQueue.
Definition at line 221 of file file_offline_queue.hpp.
|
inlineoverridevirtual |
Persists an updated attempt count for itemId, on the owner. No-op if not found.
| itemId | Id of the item whose count changed. |
| attempts | New cumulative attempt count to store. |
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 229 of file file_offline_queue.hpp.
|
inlineoverrideprotectedvirtual |
Stamps an idempotency key onto an already-enqueued item, on the owner. No-op if itemId is not found. Reachable only if a caller invokes the base IOfflineQueue::enqueue(payload, key) default through an IOfflineQueue& — this class's own enqueue(payload, key) override above stamps the key inline instead.
| itemId | Id of the item to stamp. |
| idempotencyKey | Key to store. |
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 242 of file file_offline_queue.hpp.
|
inlinenodiscardoverrideprotectedvirtual |
Enqueues on the owner, answered on replyExec.
| replyExec | Where the answer is delivered. |
| payload | Serialised action to persist. |
| idempotencyKey | Stable dedup token; may be empty. |
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 254 of file file_offline_queue.hpp.
|
inlinenodiscardoverrideprotectedvirtual |
Snapshots on the owner, answered on replyExec.
| replyExec | Where the answer is delivered. |
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 267 of file file_offline_queue.hpp.
|
inlinenodiscardoverrideprotectedvirtual |
Counts on the owner, answered on replyExec.
| replyExec | Where the answer is delivered. |
Reimplemented from morph::offline::IOfflineQueue.
Definition at line 276 of file file_offline_queue.hpp.
|
inlinenodiscard |
Snapshots the pending items on the queue's owner; delivered on replyExec.
| replyExec | Where the answer is delivered. Borrowed: it must outlive the completion. |
Definition at line 335 of file offline_queue.hpp.
|
inlinenodiscard |
Appends payload carrying idempotencyKey on the queue's owner; the new item's id is delivered on replyExec.
The form of enqueue() for a caller that is not on the queue's owner. A full queue rejects the completion with OfflineQueueFullError.
| replyExec | Where the answer is delivered, and where the caller attaches to it. Borrowed: it must outlive the completion. |
| payload | Serialised action to persist. |
| idempotencyKey | Stable dedup token for the logical op; may be empty. |
Definition at line 325 of file offline_queue.hpp.
|
inlinenodiscard |
Counts the pending items on the queue's owner; delivered on replyExec.
| replyExec | Where the answer is delivered. Borrowed: it must outlive the completion. |
Definition at line 345 of file offline_queue.hpp.