TopicSubscriptions
The subscriptions of one node that read another context's published topic: the runtime of a log's subscriptions over the topic instead, so they keep the semantics of the log's (a shared tail per partition, lanes per aggregate, a checkpoint per subscription and partition at the contiguous low watermark, parking in the ledger), with no Kafka consumer group:
Assignment: the topic's partitions are leased in the lease group
(service, "topic:<topic>")(LeaseGroup.topic) and spread over the service's nodes by HRW, by the same PartitionOwnership as a context's log; the node reads the partitions it holds, each assigned to its consumer by hand.Offsets: each subscription's checkpoint per partition is in checkpoints, under the lease group's name: the offset to read next, saved once every record before it is done with. Nothing is committed to Kafka.
One reader per (node, topic): one SubscriptionRuntime reads each held partition once and fans its records out to every subscription of the topic.
Parking: an aggregate parked by one of them is recorded in ledger with the offset of its record; retrying it re-scans that partition from there for the records keyed by the aggregate (TopicEntries); an entry whose offset the topic no longer retains is marked unrecoverable and can only be skipped.
Delivery is at least once: a handover or a restart hands over again what is past the saved checkpoint, and a subscription drops a copy of a version it remembers handling (
StateEventRecord.id).
start returns at once: the partitions are read once the topic has some, which it may not have yet when its publisher has not started, and the lease group is joined then (awaitStarted). stop hands the held partitions off, saving the checkpoints, and leaves the group.
Partitions added while it reads: every partitionRefresh it reads the topic's partitions again, and when there are more, hands the held ones off, saving their checkpoints, and joins the group again over all of them, so the new ones are read too, from their beginning. HRW gives each partition the same owner whatever their number, so the partitions held before are held again. A topic's partitions are never fewer.
Constructors
Types
Where a node is in joining a topic's lease group (joinState).
Properties
The lease group of the topic's partitions: (service, "topic:<topic>").
The attempts to join that failed since the node last joined: to read the topic's partitions (none yet counts) or to join its lease group; zero once it reads them.
Where this node is in joining the topic's lease group, for a health model to report: a node JoinState.JOINING for long reads nothing of the topic. See joinFailures for why it waits.
Why the last attempt to join failed, while joinFailures is not zero.
This node's ownership of the topic's partitions, once started.
The runtime reading the partitions, once started.
Functions
Waits until the topic's partitions are known and the lease group joined.
The partitions of the topic its subscriptions have paused on a systemic failure here.
Handles subscription's parked aggregate ref again by re-scanning its partition from the offset parked (SubscriptionRuntime.retry); this node must hold the partition. False when it was not parked, failed again, or is unrecoverable.
Resolves subscription's parked aggregate ref without handling what was skipped.
Joins the lease group in the background, as soon as the topic has partitions: reads them (retrying while it has none), then acquires this node's share and reads it, retrying until it joins: a join that fails, the lease store unreachable say, is undone and tried again after SubscriptionOptions.readRetry's backoff, and joinState stays JoinState.JOINING meanwhile.
The partitions of the topic its subscriptions throttle on backpressure here.