@relaybus/mongodb 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { EventStore, IdentifierGenerator, AppendEntry, AppendResult, ClaimRequest, ClaimedDelivery, LeaseReference, ErrorInfo, DeliveryQuery, DeliveryRecord, PurgeRequest, PurgeResult, EventStoreStatistics } from '@relaybus/core';
1
+ import { EventStore, RelayBusLogger, IdentifierGenerator, EventStoreTransactionOptions, AppendEntry, AppendResult, ClaimRequest, ClaimedDelivery, LeaseReference, ErrorInfo, DeliveryQuery, DeliveryRecord, PurgeRequest, PurgeResult, EventStoreStatistics } from '@relaybus/core';
2
2
  import { ClientSession, MongoClient, TransactionOptions } from 'mongodb';
3
3
 
4
4
  interface MongoEventStoreOptions {
@@ -6,7 +6,7 @@ interface MongoEventStoreOptions {
6
6
  readonly client: MongoClient;
7
7
  /** Database holding the relaybus collections. Default: the client's default database. */
8
8
  readonly database?: string;
9
- /** Prefix of the three collection names. Default `relaybus_`. */
9
+ /** Prefix of the collection names. Default `relaybus_`. */
10
10
  readonly collectionPrefix?: string;
11
11
  /**
12
12
  * Options of the transactions the store opens. Default: snapshot read
@@ -15,7 +15,20 @@ interface MongoEventStoreOptions {
15
15
  readonly transactionOptions?: TransactionOptions;
16
16
  /** Rows deleted per purge step. Default 500. */
17
17
  readonly purgeBatchSize?: number;
18
- /** Produces lease tokens. Default UUID v7. */
18
+ /**
19
+ * Keep an append-only record of every completed delivery in
20
+ * `<prefix>completed_deliveries`, listed as `completed`, counted by
21
+ * `statistics` and removed by `purge({ completedBefore })`. Default false: a
22
+ * completed delivery is deleted and leaves nothing behind. Use the same value
23
+ * in every process.
24
+ */
25
+ readonly completionHistory?: boolean;
26
+ /** Receives warnings about best-effort steps that failed (parking). Default `console`. */
27
+ readonly logger?: RelayBusLogger;
28
+ /**
29
+ * @deprecated Ignored. Lease tokens name the lane and its epoch
30
+ * (`<laneId>:<epoch>:<claims>`) and are no longer generated.
31
+ */
19
32
  readonly generateIdentifier?: IdentifierGenerator;
20
33
  }
21
34
  /**
@@ -24,29 +37,75 @@ interface MongoEventStoreOptions {
24
37
  * session can carry your own writes (native driver or Mongoose).
25
38
  *
26
39
  * Guarantees:
27
- * - `append` is atomic with the caller's writes and idempotent on event id and on
28
- * (event id, handler). Duplicates are detected by reading, never by catching a
40
+ * - **Atomic, idempotent append.** `append` is atomic with the caller's writes
41
+ * and idempotent on event id and on (event id, handler). An event remembers
42
+ * every handler it ever had a delivery for, so a redelivered or republished
43
+ * event never runs a completed handler again although completed deliveries are
44
+ * deleted. Duplicates are detected by reading, never by catching a
29
45
  * duplicate-key error, which would abort the surrounding transaction.
30
- * - Per-key sequences are allocated from a counter document inside the append
31
- * transaction. Two transactions appending the same key cannot both hold the
32
- * counter, so the loser conflicts, restarts after the winner committed, and
33
- * its sequence is higher: sequence order is commit order.
34
- * - `claim` selects candidates, then takes each with a conditional update that
35
- * re-checks the exact state it selected, so exactly one claimer wins. A keyed
36
- * delivery waits while an earlier delivery of its handler and key is
37
- * unfinished, or while any other delivery of them runs under a live lease;
38
- * the second rule is re-checked after the update, so a dead letter requeued
39
- * during a claim cannot run alongside its successor.
40
- * - Every lease operation is fenced by delivery id, status and lease token.
46
+ * - **Per-key order.** Per-key sequences come from a counter document inside the
47
+ * append transaction. Two transactions appending the same key cannot both hold
48
+ * the counter, so the loser conflicts, restarts after the winner committed, and
49
+ * its sequence is higher: sequence order is commit order. A keyed delivery is
50
+ * claimed only when no earlier delivery of its handler and key is pending and
51
+ * no other delivery of them runs.
52
+ * - **Lane leases.** Every delivery belongs to one of 256 lanes (a hash of its
53
+ * ordering key, or of its event id), so all deliveries of a key share a lane.
54
+ * Workers lease lanes with one conditional write on a lane document, and a
55
+ * claim records its whole batch in the lane documents: it writes no delivery
56
+ * document. While a lane lease is live, other workers do not see the pending
57
+ * deliveries of that lane, even idle ones. A lane changes hands only when its
58
+ * lease expired or its owner handed it back.
59
+ * - **Fencing.** A lease token is `<laneId>:<epoch>:<claims>`. The epoch grows
60
+ * whenever the lane is taken; `claims`, the delivery's claim generation, grows
61
+ * whenever a claim of it ends (retry, release, burial, lost lease), so the
62
+ * lease of an earlier claim never matches a later claim of the same delivery
63
+ * in the same lane epoch. Completion, retry, burial, release and renewal apply
64
+ * only while the lane has that epoch, lists the delivery as in flight, and the
65
+ * delivery has that claim generation.
66
+ * - **Effectively-once for transactional handlers.** A worker that takes a lane
67
+ * over first writes every delivery the previous owner had in flight (it
68
+ * charges the lost attempt) and only then reads what to claim. A completion
69
+ * inside a transaction (a transactional handler's, or any completion when a
70
+ * completion history is kept) deletes the delivery after checking the lane:
71
+ * both write the same delivery document, so the later of the two either
72
+ * conflicts and retries (and then sees the new epoch or the missing
73
+ * delivery), or waits for the earlier to commit. Other completions run
74
+ * without a transaction: they read the deliveries' claim generations, then
75
+ * the lanes, and delete only deliveries whose generation did not change,
76
+ * which a takeover, a retry or a release always changes. Either way a completion and a takeover
77
+ * cannot both succeed. Completions never write the lane document, so
78
+ * concurrent completions of one lane never conflict with each other.
79
+ * - **Attempts survive crashes.** `attempts` counts attempts that ended. The
80
+ * claim result reports `attempts + 1`; a failure records it; a lane taken over
81
+ * charges one attempt to every delivery the previous owner still had in flight,
82
+ * so a poison message still reaches the retry limit after crashes.
83
+ *
84
+ * - **Deduplication record.** A completion records its time on the event
85
+ * (`completedAt`). An event nothing references any more stays until
86
+ * `purge({ completedBefore })` passes that time, however old the event is, and
87
+ * `deadBefore` alone never removes it. Once purged, the event takes its list
88
+ * of handlers with it: a broker redelivery or publish retry of that event id
89
+ * afterwards is appended as a new event and runs its handlers again, as in
90
+ * the PostgreSQL store, so keep completed retention longer than any
91
+ * redelivery window.
41
92
  *
42
93
  * `transaction` may run `work` more than once (see {@link MongoEventStore.transaction}).
94
+ * Claims of one `leaseOwner` on one store instance run one after the other
95
+ * (a claim that overlaps another of the same owner waits for it); different
96
+ * owners claim concurrently, from any number of processes. Lanes are held per store
97
+ * instance, so a process restarted with the same `leaseOwner` takes its
98
+ * predecessor's lanes over only once their leases expired.
43
99
  */
44
100
  declare class MongoEventStore implements EventStore<ClientSession> {
45
101
  #private;
46
102
  constructor(options: MongoEventStoreOptions);
47
103
  /**
48
- * Verifies the deployment supports transactions and creates the indexes.
49
- * Safe to run repeatedly and from several processes.
104
+ * Verifies the deployment supports transactions, creates the collections and
105
+ * indexes and seeds the lane documents. Upgrades a 0.1.0 database in place
106
+ * first (see `MongoSchema.#upgradeFromVersion010`); the seeded lanes
107
+ * mark the upgrade as done, so later runs skip it. Safe to run repeatedly and
108
+ * from several processes. Stop 0.1.0 workers before the first run.
50
109
  *
51
110
  * @throws ConfigurationError when the server is a standalone mongod.
52
111
  */
@@ -61,19 +120,99 @@ declare class MongoEventStore implements EventStore<ClientSession> {
61
120
  * not safe for side effects outside the session (HTTP calls, other databases),
62
121
  * so keep those out of `work`; relaybus handlers are already at-least-once.
63
122
  *
123
+ * With `options.timeoutMs` (from `bus.transaction`) the server bounds the commit with
124
+ * `maxCommitTimeMS`; the bus aborts a transaction that ran past the budget before its commit.
125
+ *
64
126
  * @throws ConfigurationError when the deployment does not support transactions.
65
127
  */
66
- transaction<T>(work: (transaction: ClientSession) => Promise<T>): Promise<T>;
128
+ transaction<T>(work: (transaction: ClientSession) => Promise<T>, options?: EventStoreTransactionOptions): Promise<T>;
129
+ /**
130
+ * Writes the entries in `session`. An existing event gets a delivery only for
131
+ * handlers it does not list yet; the added handlers are appended to its list
132
+ * together with a `revision` increment, a real write that makes a concurrent
133
+ * purge of the event conflict with this transaction.
134
+ */
67
135
  append(session: ClientSession, entries: readonly AppendEntry[], now: Date): Promise<AppendResult>;
136
+ /**
137
+ * Claims up to `limit` due deliveries. It claims from the lanes this owner
138
+ * (and this store instance) holds under a live lease first, then takes free
139
+ * lanes with due work, a few at a time (4, 8, 16, ...) and the lane with the
140
+ * oldest due delivery first, so a worker holds only as many lanes as it
141
+ * needs. It then records the batch with one write per lane and hands back the
142
+ * lanes that yielded nothing and run nothing. No delivery document is
143
+ * written, except for the attempt charged to deliveries of a lane taken over
144
+ * and for parking (see `MongoOrdering.#parkDeliveries`).
145
+ *
146
+ * Taking a lane is one conditional `findOneAndUpdate` that also moves the
147
+ * previous owner's in-flight list to the lane's `lost` list; a lane another
148
+ * claimer took first is skipped, never waited for. Lost deliveries are charged
149
+ * one attempt before anything is read from the lane, and `lost` is cleared
150
+ * only after that. Whoever holds the lane next charges a `lost` list it finds
151
+ * first, so a claim that fails anywhere after the take loses no charge; the
152
+ * charge of a lost claim is recorded on the delivery, so charging the list
153
+ * again after a failure before the clear charges nothing twice.
154
+ * Nothing a failed claim did leaves a delivery listed as running.
155
+ */
68
156
  claim(request: ClaimRequest): Promise<ClaimedDelivery[]>;
69
- extendLease(lease: LeaseReference, leaseExpiresAt: Date, now: Date): Promise<boolean>;
157
+ /**
158
+ * Extends the lease of the lane a running delivery belongs to. The lane lease
159
+ * never shrinks, so a repeated renewal with the same value still holds. An
160
+ * expired lease nobody took over is still renewed, so `_now` is not needed.
161
+ */
162
+ extendLease(lease: LeaseReference, leaseExpiresAt: Date, _now?: Date): Promise<boolean>;
163
+ /**
164
+ * Deletes the delivery (and records it in the completion history, when kept).
165
+ * With `session` the deletion commits with the caller's transaction; without,
166
+ * it runs in a transaction of its own. Returns false when the lease was lost.
167
+ */
70
168
  complete(lease: LeaseReference, now: Date, session?: ClientSession): Promise<boolean>;
169
+ /**
170
+ * Completes many leases with a fixed number of round trips, whatever lanes
171
+ * they belong to: three commands without a completion history, one
172
+ * transaction with it (see `MongoCompletion.#deleteFenced`).
173
+ * Returns one flag per lease in input order; a lease listed twice completes
174
+ * once, and a token this store cannot have issued is refused.
175
+ */
176
+ completeMany(leases: readonly LeaseReference[], now: Date): Promise<boolean[]>;
177
+ /** Returns a running delivery to pending, due at `availableAt`, and counts the attempt that ended. */
71
178
  reschedule(lease: LeaseReference, availableAt: Date, error: ErrorInfo, now: Date): Promise<boolean>;
179
+ /** Gives a running delivery back without counting the attempt: pending, due `now`. */
72
180
  release(lease: LeaseReference, now: Date): Promise<boolean>;
181
+ /** Moves a running delivery to dead and counts the attempt that ended. */
73
182
  bury(lease: LeaseReference, error: ErrorInfo, now: Date): Promise<boolean>;
183
+ /**
184
+ * Frees every lane `leaseOwner` holds that runs no delivery, so other workers
185
+ * need not wait for the lease to expire. Lanes with running deliveries stay leased.
186
+ */
187
+ relinquish(leaseOwner: string): Promise<void>;
188
+ /**
189
+ * Lists deliveries in creation order. A delivery is `processing` while its
190
+ * document exists as `pending` and its lane lists it; its attempt count then
191
+ * includes the running attempt, and owner and expiry are those of the lane
192
+ * lease. Completion history records (when kept) are listed as `completed`.
193
+ */
74
194
  listDeliveries(query: DeliveryQuery): Promise<DeliveryRecord[]>;
195
+ /** Moves dead deliveries back to pending with a fresh attempt budget. */
75
196
  requeue(deliveryIds: readonly string[], now: Date): Promise<number>;
197
+ /**
198
+ * Deletes, in batches of `purgeBatchSize`, dead deliveries last updated before
199
+ * `deadBefore`, and completion history records (and `completed` documents left
200
+ * by 0.1.0) completed before `completedBefore`, each batch in one transaction
201
+ * together with the events it left without any reference. Finally, events
202
+ * nothing references are deleted: one with a completed delivery once its last
203
+ * completion is before `completedBefore` (never by `deadBefore` alone), one
204
+ * that never had a completion (no subscribers, or only dead letters) once it
205
+ * was created before the earliest given cutoff. The batch step applies the
206
+ * same rule to events whose last completion is recorded.
207
+ */
76
208
  purge(request: PurgeRequest): Promise<PurgeResult>;
209
+ /**
210
+ * Counts by derived status. `pending` excludes running deliveries; `completed`
211
+ * counts history records and 0.1.0 `completed` documents. `oldestDueAt` is the
212
+ * oldest instant at which a delivery became claimable: the due time of a
213
+ * pending delivery nobody runs, or the lease expiry of a lane that still runs
214
+ * deliveries.
215
+ */
77
216
  statistics(now: Date): Promise<EventStoreStatistics>;
78
217
  }
79
218
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { EventStore, IdentifierGenerator, AppendEntry, AppendResult, ClaimRequest, ClaimedDelivery, LeaseReference, ErrorInfo, DeliveryQuery, DeliveryRecord, PurgeRequest, PurgeResult, EventStoreStatistics } from '@relaybus/core';
1
+ import { EventStore, RelayBusLogger, IdentifierGenerator, EventStoreTransactionOptions, AppendEntry, AppendResult, ClaimRequest, ClaimedDelivery, LeaseReference, ErrorInfo, DeliveryQuery, DeliveryRecord, PurgeRequest, PurgeResult, EventStoreStatistics } from '@relaybus/core';
2
2
  import { ClientSession, MongoClient, TransactionOptions } from 'mongodb';
3
3
 
4
4
  interface MongoEventStoreOptions {
@@ -6,7 +6,7 @@ interface MongoEventStoreOptions {
6
6
  readonly client: MongoClient;
7
7
  /** Database holding the relaybus collections. Default: the client's default database. */
8
8
  readonly database?: string;
9
- /** Prefix of the three collection names. Default `relaybus_`. */
9
+ /** Prefix of the collection names. Default `relaybus_`. */
10
10
  readonly collectionPrefix?: string;
11
11
  /**
12
12
  * Options of the transactions the store opens. Default: snapshot read
@@ -15,7 +15,20 @@ interface MongoEventStoreOptions {
15
15
  readonly transactionOptions?: TransactionOptions;
16
16
  /** Rows deleted per purge step. Default 500. */
17
17
  readonly purgeBatchSize?: number;
18
- /** Produces lease tokens. Default UUID v7. */
18
+ /**
19
+ * Keep an append-only record of every completed delivery in
20
+ * `<prefix>completed_deliveries`, listed as `completed`, counted by
21
+ * `statistics` and removed by `purge({ completedBefore })`. Default false: a
22
+ * completed delivery is deleted and leaves nothing behind. Use the same value
23
+ * in every process.
24
+ */
25
+ readonly completionHistory?: boolean;
26
+ /** Receives warnings about best-effort steps that failed (parking). Default `console`. */
27
+ readonly logger?: RelayBusLogger;
28
+ /**
29
+ * @deprecated Ignored. Lease tokens name the lane and its epoch
30
+ * (`<laneId>:<epoch>:<claims>`) and are no longer generated.
31
+ */
19
32
  readonly generateIdentifier?: IdentifierGenerator;
20
33
  }
21
34
  /**
@@ -24,29 +37,75 @@ interface MongoEventStoreOptions {
24
37
  * session can carry your own writes (native driver or Mongoose).
25
38
  *
26
39
  * Guarantees:
27
- * - `append` is atomic with the caller's writes and idempotent on event id and on
28
- * (event id, handler). Duplicates are detected by reading, never by catching a
40
+ * - **Atomic, idempotent append.** `append` is atomic with the caller's writes
41
+ * and idempotent on event id and on (event id, handler). An event remembers
42
+ * every handler it ever had a delivery for, so a redelivered or republished
43
+ * event never runs a completed handler again although completed deliveries are
44
+ * deleted. Duplicates are detected by reading, never by catching a
29
45
  * duplicate-key error, which would abort the surrounding transaction.
30
- * - Per-key sequences are allocated from a counter document inside the append
31
- * transaction. Two transactions appending the same key cannot both hold the
32
- * counter, so the loser conflicts, restarts after the winner committed, and
33
- * its sequence is higher: sequence order is commit order.
34
- * - `claim` selects candidates, then takes each with a conditional update that
35
- * re-checks the exact state it selected, so exactly one claimer wins. A keyed
36
- * delivery waits while an earlier delivery of its handler and key is
37
- * unfinished, or while any other delivery of them runs under a live lease;
38
- * the second rule is re-checked after the update, so a dead letter requeued
39
- * during a claim cannot run alongside its successor.
40
- * - Every lease operation is fenced by delivery id, status and lease token.
46
+ * - **Per-key order.** Per-key sequences come from a counter document inside the
47
+ * append transaction. Two transactions appending the same key cannot both hold
48
+ * the counter, so the loser conflicts, restarts after the winner committed, and
49
+ * its sequence is higher: sequence order is commit order. A keyed delivery is
50
+ * claimed only when no earlier delivery of its handler and key is pending and
51
+ * no other delivery of them runs.
52
+ * - **Lane leases.** Every delivery belongs to one of 256 lanes (a hash of its
53
+ * ordering key, or of its event id), so all deliveries of a key share a lane.
54
+ * Workers lease lanes with one conditional write on a lane document, and a
55
+ * claim records its whole batch in the lane documents: it writes no delivery
56
+ * document. While a lane lease is live, other workers do not see the pending
57
+ * deliveries of that lane, even idle ones. A lane changes hands only when its
58
+ * lease expired or its owner handed it back.
59
+ * - **Fencing.** A lease token is `<laneId>:<epoch>:<claims>`. The epoch grows
60
+ * whenever the lane is taken; `claims`, the delivery's claim generation, grows
61
+ * whenever a claim of it ends (retry, release, burial, lost lease), so the
62
+ * lease of an earlier claim never matches a later claim of the same delivery
63
+ * in the same lane epoch. Completion, retry, burial, release and renewal apply
64
+ * only while the lane has that epoch, lists the delivery as in flight, and the
65
+ * delivery has that claim generation.
66
+ * - **Effectively-once for transactional handlers.** A worker that takes a lane
67
+ * over first writes every delivery the previous owner had in flight (it
68
+ * charges the lost attempt) and only then reads what to claim. A completion
69
+ * inside a transaction (a transactional handler's, or any completion when a
70
+ * completion history is kept) deletes the delivery after checking the lane:
71
+ * both write the same delivery document, so the later of the two either
72
+ * conflicts and retries (and then sees the new epoch or the missing
73
+ * delivery), or waits for the earlier to commit. Other completions run
74
+ * without a transaction: they read the deliveries' claim generations, then
75
+ * the lanes, and delete only deliveries whose generation did not change,
76
+ * which a takeover, a retry or a release always changes. Either way a completion and a takeover
77
+ * cannot both succeed. Completions never write the lane document, so
78
+ * concurrent completions of one lane never conflict with each other.
79
+ * - **Attempts survive crashes.** `attempts` counts attempts that ended. The
80
+ * claim result reports `attempts + 1`; a failure records it; a lane taken over
81
+ * charges one attempt to every delivery the previous owner still had in flight,
82
+ * so a poison message still reaches the retry limit after crashes.
83
+ *
84
+ * - **Deduplication record.** A completion records its time on the event
85
+ * (`completedAt`). An event nothing references any more stays until
86
+ * `purge({ completedBefore })` passes that time, however old the event is, and
87
+ * `deadBefore` alone never removes it. Once purged, the event takes its list
88
+ * of handlers with it: a broker redelivery or publish retry of that event id
89
+ * afterwards is appended as a new event and runs its handlers again, as in
90
+ * the PostgreSQL store, so keep completed retention longer than any
91
+ * redelivery window.
41
92
  *
42
93
  * `transaction` may run `work` more than once (see {@link MongoEventStore.transaction}).
94
+ * Claims of one `leaseOwner` on one store instance run one after the other
95
+ * (a claim that overlaps another of the same owner waits for it); different
96
+ * owners claim concurrently, from any number of processes. Lanes are held per store
97
+ * instance, so a process restarted with the same `leaseOwner` takes its
98
+ * predecessor's lanes over only once their leases expired.
43
99
  */
44
100
  declare class MongoEventStore implements EventStore<ClientSession> {
45
101
  #private;
46
102
  constructor(options: MongoEventStoreOptions);
47
103
  /**
48
- * Verifies the deployment supports transactions and creates the indexes.
49
- * Safe to run repeatedly and from several processes.
104
+ * Verifies the deployment supports transactions, creates the collections and
105
+ * indexes and seeds the lane documents. Upgrades a 0.1.0 database in place
106
+ * first (see `MongoSchema.#upgradeFromVersion010`); the seeded lanes
107
+ * mark the upgrade as done, so later runs skip it. Safe to run repeatedly and
108
+ * from several processes. Stop 0.1.0 workers before the first run.
50
109
  *
51
110
  * @throws ConfigurationError when the server is a standalone mongod.
52
111
  */
@@ -61,19 +120,99 @@ declare class MongoEventStore implements EventStore<ClientSession> {
61
120
  * not safe for side effects outside the session (HTTP calls, other databases),
62
121
  * so keep those out of `work`; relaybus handlers are already at-least-once.
63
122
  *
123
+ * With `options.timeoutMs` (from `bus.transaction`) the server bounds the commit with
124
+ * `maxCommitTimeMS`; the bus aborts a transaction that ran past the budget before its commit.
125
+ *
64
126
  * @throws ConfigurationError when the deployment does not support transactions.
65
127
  */
66
- transaction<T>(work: (transaction: ClientSession) => Promise<T>): Promise<T>;
128
+ transaction<T>(work: (transaction: ClientSession) => Promise<T>, options?: EventStoreTransactionOptions): Promise<T>;
129
+ /**
130
+ * Writes the entries in `session`. An existing event gets a delivery only for
131
+ * handlers it does not list yet; the added handlers are appended to its list
132
+ * together with a `revision` increment, a real write that makes a concurrent
133
+ * purge of the event conflict with this transaction.
134
+ */
67
135
  append(session: ClientSession, entries: readonly AppendEntry[], now: Date): Promise<AppendResult>;
136
+ /**
137
+ * Claims up to `limit` due deliveries. It claims from the lanes this owner
138
+ * (and this store instance) holds under a live lease first, then takes free
139
+ * lanes with due work, a few at a time (4, 8, 16, ...) and the lane with the
140
+ * oldest due delivery first, so a worker holds only as many lanes as it
141
+ * needs. It then records the batch with one write per lane and hands back the
142
+ * lanes that yielded nothing and run nothing. No delivery document is
143
+ * written, except for the attempt charged to deliveries of a lane taken over
144
+ * and for parking (see `MongoOrdering.#parkDeliveries`).
145
+ *
146
+ * Taking a lane is one conditional `findOneAndUpdate` that also moves the
147
+ * previous owner's in-flight list to the lane's `lost` list; a lane another
148
+ * claimer took first is skipped, never waited for. Lost deliveries are charged
149
+ * one attempt before anything is read from the lane, and `lost` is cleared
150
+ * only after that. Whoever holds the lane next charges a `lost` list it finds
151
+ * first, so a claim that fails anywhere after the take loses no charge; the
152
+ * charge of a lost claim is recorded on the delivery, so charging the list
153
+ * again after a failure before the clear charges nothing twice.
154
+ * Nothing a failed claim did leaves a delivery listed as running.
155
+ */
68
156
  claim(request: ClaimRequest): Promise<ClaimedDelivery[]>;
69
- extendLease(lease: LeaseReference, leaseExpiresAt: Date, now: Date): Promise<boolean>;
157
+ /**
158
+ * Extends the lease of the lane a running delivery belongs to. The lane lease
159
+ * never shrinks, so a repeated renewal with the same value still holds. An
160
+ * expired lease nobody took over is still renewed, so `_now` is not needed.
161
+ */
162
+ extendLease(lease: LeaseReference, leaseExpiresAt: Date, _now?: Date): Promise<boolean>;
163
+ /**
164
+ * Deletes the delivery (and records it in the completion history, when kept).
165
+ * With `session` the deletion commits with the caller's transaction; without,
166
+ * it runs in a transaction of its own. Returns false when the lease was lost.
167
+ */
70
168
  complete(lease: LeaseReference, now: Date, session?: ClientSession): Promise<boolean>;
169
+ /**
170
+ * Completes many leases with a fixed number of round trips, whatever lanes
171
+ * they belong to: three commands without a completion history, one
172
+ * transaction with it (see `MongoCompletion.#deleteFenced`).
173
+ * Returns one flag per lease in input order; a lease listed twice completes
174
+ * once, and a token this store cannot have issued is refused.
175
+ */
176
+ completeMany(leases: readonly LeaseReference[], now: Date): Promise<boolean[]>;
177
+ /** Returns a running delivery to pending, due at `availableAt`, and counts the attempt that ended. */
71
178
  reschedule(lease: LeaseReference, availableAt: Date, error: ErrorInfo, now: Date): Promise<boolean>;
179
+ /** Gives a running delivery back without counting the attempt: pending, due `now`. */
72
180
  release(lease: LeaseReference, now: Date): Promise<boolean>;
181
+ /** Moves a running delivery to dead and counts the attempt that ended. */
73
182
  bury(lease: LeaseReference, error: ErrorInfo, now: Date): Promise<boolean>;
183
+ /**
184
+ * Frees every lane `leaseOwner` holds that runs no delivery, so other workers
185
+ * need not wait for the lease to expire. Lanes with running deliveries stay leased.
186
+ */
187
+ relinquish(leaseOwner: string): Promise<void>;
188
+ /**
189
+ * Lists deliveries in creation order. A delivery is `processing` while its
190
+ * document exists as `pending` and its lane lists it; its attempt count then
191
+ * includes the running attempt, and owner and expiry are those of the lane
192
+ * lease. Completion history records (when kept) are listed as `completed`.
193
+ */
74
194
  listDeliveries(query: DeliveryQuery): Promise<DeliveryRecord[]>;
195
+ /** Moves dead deliveries back to pending with a fresh attempt budget. */
75
196
  requeue(deliveryIds: readonly string[], now: Date): Promise<number>;
197
+ /**
198
+ * Deletes, in batches of `purgeBatchSize`, dead deliveries last updated before
199
+ * `deadBefore`, and completion history records (and `completed` documents left
200
+ * by 0.1.0) completed before `completedBefore`, each batch in one transaction
201
+ * together with the events it left without any reference. Finally, events
202
+ * nothing references are deleted: one with a completed delivery once its last
203
+ * completion is before `completedBefore` (never by `deadBefore` alone), one
204
+ * that never had a completion (no subscribers, or only dead letters) once it
205
+ * was created before the earliest given cutoff. The batch step applies the
206
+ * same rule to events whose last completion is recorded.
207
+ */
76
208
  purge(request: PurgeRequest): Promise<PurgeResult>;
209
+ /**
210
+ * Counts by derived status. `pending` excludes running deliveries; `completed`
211
+ * counts history records and 0.1.0 `completed` documents. `oldestDueAt` is the
212
+ * oldest instant at which a delivery became claimable: the due time of a
213
+ * pending delivery nobody runs, or the lease expiry of a lane that still runs
214
+ * deliveries.
215
+ */
77
216
  statistics(now: Date): Promise<EventStoreStatistics>;
78
217
  }
79
218