LedgerPublisher
Publishes a service's failure ledger to the ops context: each entry as a LedgerEntry to the ops aggregate Ledger.parkedId names, through the command topic of LedgerPublishing.context (send), and each entry that is no longer parked as a LedgerResolution.
When: at once when an entry parks or spends its retries (the node's ParkedNotifier), and when an operator's ledger command acts on one (parked, resolved); and on every scan, every LedgerPublishing.interval, the reconciliation loop: every entry whose partition this node runs (ParkedOps.owns) is published again, and an entry this node published that has since left the ledger, not to another owner, is published as resolved. A record that is lost (the broker down, the node killed) is so published again; one entry's failure does not stop the others. A resolution whose send failed is kept in memory as it was and sent again by each scan of this node, whether or not it still runs the partition, until it is delivered, the aggregate is published parked again first, or the node stops.
Idempotence: a record's request id is deterministic: a digest of the entry's ops id and its content, and of when this node first saw that content, so a record sent twice is one request to the ops aggregate, while an entry that comes back to an earlier content (an operator's request taken, say) is a new request. The ops aggregate ignores a record that changes nothing, so the records a scan sends again leave its log as it is.
Operator: the records are a framework component's,
system:ledger.
After a restart the node no longer knows what it published, nor the resolutions it had not sent yet: an entry resolved while it was down, or whose resolution it had not delivered, stays parked in the ops view until an operator acts on it there, which the owning service answers with LedgerResolution.NOT_PARKED.
With available (an LedgerPublishing.automatic publishing), it publishes only while available says the ops context can take the records: asked at start and every availability after. While it cannot, nothing is sent and the entries stay in the ledger; once it can, a scan at once publishes them all. Each change is logged once.
Properties
Functions
Runs action, an operator's action on subscription's entry of ref that publishes what came of it, while the scans leave the entry alone: a scan between the action resolving the entry and publishing its outcome would otherwise publish it as LedgerResolution.RESOLVED first, and the ops view keeps the first resolution.
Publishes view's entry as parked.
Publishes that subscription no longer parks ref, since outcome; failedAt the parking's, when known.
Starts the reconciliation loop: a scan now and every LedgerPublishing.interval; with available, asks it now and every availability first.