@boxxy/dispatch 0.1.1 → 0.1.3
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/attempts/attempt-machine.d.ts +804 -0
- package/dist/attempts/attempt-moves.d.ts +2 -0
- package/dist/attempts/bind-attempt-session.d.ts +14 -0
- package/dist/attempts/build-attempt-change.d.ts +73 -0
- package/dist/attempts/build-attempt-fact.d.ts +3 -0
- package/dist/attempts/end-item-attempts.d.ts +18 -0
- package/dist/attempts/is-same-guard.d.ts +5 -0
- package/dist/attempts/pick-call-attempt.d.ts +10 -0
- package/dist/attempts/stop-stray-session.d.ts +11 -0
- package/dist/attempts/types.d.ts +142 -0
- package/dist/attempts/write-attempt-move.d.ts +7 -0
- package/dist/attempts/write-session-bind.d.ts +3 -0
- package/dist/claims/build-snapshot-hash.d.ts +2 -0
- package/dist/claims/claim-next.d.ts +6 -0
- package/dist/claims/pick-kept-session.d.ts +9 -0
- package/dist/claims/request-wake.d.ts +3 -0
- package/dist/claims/resume-claim.d.ts +3 -0
- package/dist/claims/start-claim.d.ts +3 -0
- package/dist/claims/types.d.ts +44 -0
- package/dist/closeouts/build-settle-plans.d.ts +17 -0
- package/dist/closeouts/close-out-attempt.d.ts +3 -0
- package/dist/closeouts/effect-handlers.d.ts +2 -0
- package/dist/closeouts/pick-settlement.d.ts +14 -0
- package/dist/closeouts/settle-attempt.d.ts +3 -0
- package/dist/closeouts/types.d.ts +50 -0
- package/dist/index.d.ts +38 -0
- package/dist/notices/constants.d.ts +4 -0
- package/dist/notices/create-null-notifier.d.ts +2 -0
- package/dist/notices/send-notices.d.ts +2 -0
- package/dist/notices/types.d.ts +11 -0
- package/dist/outbox/build-backoff-ms.d.ts +2 -0
- package/dist/outbox/build-initial-sender-state.d.ts +2 -0
- package/dist/outbox/build-outbox-status.d.ts +15 -0
- package/dist/outbox/constants.d.ts +2 -0
- package/dist/outbox/measure-wire-bytes.d.ts +2 -0
- package/dist/outbox/pick-sender-move.d.ts +10 -0
- package/dist/outbox/run-sender-once.d.ts +2 -0
- package/dist/outbox/take-batch.d.ts +3 -0
- package/dist/outbox/types.d.ts +61 -0
- package/dist/pull-requests/build-link-change.d.ts +11 -0
- package/dist/pull-requests/build-state-fact.d.ts +8 -0
- package/dist/pull-requests/collect-attempt-trailers.d.ts +2 -0
- package/dist/pull-requests/collect-seen-state.d.ts +7 -0
- package/dist/pull-requests/constants.d.ts +3 -0
- package/dist/pull-requests/link-pull-request.d.ts +2 -0
- package/dist/pull-requests/parse-pull-request-url.d.ts +2 -0
- package/dist/pull-requests/types.d.ts +37 -0
- package/dist/pull-requests/watch-pull-requests.d.ts +2 -0
- package/dist/readings/act-on-reading.d.ts +3 -0
- package/dist/readings/find-waiting-since.d.ts +9 -0
- package/dist/readings/pick-reading-action.d.ts +2 -0
- package/dist/readings/types.d.ts +79 -0
- package/dist/sessions/build-keep-writes.d.ts +9 -0
- package/dist/sessions/build-kept-clear.d.ts +2 -0
- package/dist/sessions/forget-sessions.d.ts +2 -0
- package/dist/sessions/is-kept-due.d.ts +2 -0
- package/dist/sessions/resume-kept-session.d.ts +6 -0
- package/dist/sessions/types.d.ts +19 -0
- package/dist/test-utils/apply-memory-change.d.ts +3 -0
- package/dist/test-utils/build-memory-reader.d.ts +3 -0
- package/dist/test-utils/build-mock-claim-change.d.ts +2 -2
- package/dist/test-utils/build-mock-new-id.d.ts +2 -0
- package/dist/test-utils/build-mock-note-change.d.ts +2 -0
- package/dist/test-utils/build-mock-pull-request-change.d.ts +1 -0
- package/dist/test-utils/{build-mock-link-change.d.ts → build-mock-relation-change.d.ts} +2 -2
- package/dist/test-utils/build-mock-running-reading.d.ts +6 -0
- package/dist/test-utils/build-mock-start-change.d.ts +2 -2
- package/dist/test-utils/claim-store-close-cases.d.ts +2 -0
- package/dist/test-utils/claim-store-copy-cases.d.ts +2 -0
- package/dist/test-utils/claim-store-outbox-cases.d.ts +2 -0
- package/dist/test-utils/claim-store-race-cases.d.ts +2 -0
- package/dist/test-utils/claim-store-seat-cases.d.ts +2 -0
- package/dist/test-utils/claim-store-session-cases.d.ts +2 -0
- package/dist/test-utils/collect-memory-limit-fills.d.ts +3 -0
- package/dist/test-utils/compare-text.d.ts +1 -0
- package/dist/test-utils/create-fake-backoff.d.ts +2 -0
- package/dist/test-utils/create-fake-clock.d.ts +5 -0
- package/dist/test-utils/create-fake-fact-sink.d.ts +8 -0
- package/dist/test-utils/create-fake-forge.d.ts +17 -0
- package/dist/test-utils/create-fake-worker.d.ts +42 -0
- package/dist/test-utils/create-memory-claim-store.d.ts +2 -2
- package/dist/test-utils/create-test-dispatch.d.ts +46 -0
- package/dist/test-utils/forge-contract.d.ts +15 -0
- package/dist/test-utils/is-same-held-seat.d.ts +2 -0
- package/dist/test-utils/types.d.ts +12 -2
- package/dist/test-utils/worker-contract.d.ts +14 -0
- package/dist/timeouts.d.ts +2 -0
- package/dist/types.d.ts +13 -0
- package/package.json +10 -3
- package/src/attempts/attempt-machine.ts +147 -0
- package/src/attempts/attempt-moves.ts +218 -0
- package/src/attempts/bind-attempt-session.ts +61 -0
- package/src/attempts/build-attempt-change.ts +540 -0
- package/src/attempts/build-attempt-fact.ts +135 -0
- package/src/attempts/end-item-attempts.ts +95 -0
- package/src/attempts/is-same-guard.ts +22 -0
- package/src/attempts/pick-call-attempt.ts +32 -0
- package/src/attempts/stop-stray-session.ts +48 -0
- package/src/attempts/types.ts +231 -0
- package/src/attempts/write-attempt-move.ts +41 -0
- package/src/attempts/write-session-bind.ts +47 -0
- package/src/claims/build-snapshot-hash.ts +9 -0
- package/src/claims/claim-next.ts +306 -0
- package/src/claims/pick-kept-session.ts +41 -0
- package/src/claims/request-wake.ts +17 -0
- package/src/claims/resume-claim.ts +56 -0
- package/src/claims/start-claim.ts +99 -0
- package/src/claims/types.ts +67 -0
- package/src/closeouts/build-settle-plans.ts +173 -0
- package/src/closeouts/close-out-attempt.ts +156 -0
- package/src/closeouts/effect-handlers.ts +232 -0
- package/src/closeouts/pick-settlement.ts +80 -0
- package/src/closeouts/settle-attempt.ts +161 -0
- package/src/closeouts/types.ts +87 -0
- package/src/index.ts +61 -0
- package/src/notices/constants.ts +7 -0
- package/src/notices/create-null-notifier.ts +6 -0
- package/src/notices/send-notices.ts +41 -0
- package/src/notices/types.ts +14 -0
- package/src/outbox/build-backoff-ms.ts +14 -0
- package/src/outbox/build-initial-sender-state.ts +14 -0
- package/src/outbox/build-outbox-status.ts +43 -0
- package/src/outbox/constants.ts +15 -0
- package/src/outbox/measure-wire-bytes.ts +31 -0
- package/src/outbox/pick-sender-move.ts +37 -0
- package/src/outbox/run-sender-once.ts +174 -0
- package/src/outbox/take-batch.ts +35 -0
- package/src/outbox/types.ts +76 -0
- package/src/pull-requests/build-link-change.ts +95 -0
- package/src/pull-requests/build-state-fact.ts +39 -0
- package/src/pull-requests/collect-attempt-trailers.ts +20 -0
- package/src/pull-requests/collect-seen-state.ts +19 -0
- package/src/pull-requests/constants.ts +5 -0
- package/src/pull-requests/link-pull-request.ts +119 -0
- package/src/pull-requests/parse-pull-request-url.ts +30 -0
- package/src/pull-requests/types.ts +63 -0
- package/src/pull-requests/watch-pull-requests.ts +308 -0
- package/src/readings/act-on-reading.ts +318 -0
- package/src/readings/find-waiting-since.ts +46 -0
- package/src/readings/pick-reading-action.ts +315 -0
- package/src/readings/types.ts +98 -0
- package/src/sessions/build-keep-writes.ts +55 -0
- package/src/sessions/build-kept-clear.ts +12 -0
- package/src/sessions/forget-sessions.ts +106 -0
- package/src/sessions/is-kept-due.ts +27 -0
- package/src/sessions/resume-kept-session.ts +25 -0
- package/src/sessions/types.ts +39 -0
- package/src/test-utils/apply-memory-change.ts +252 -0
- package/src/test-utils/build-memory-reader.ts +364 -0
- package/src/test-utils/build-mock-bind-change.ts +18 -11
- package/src/test-utils/build-mock-claim-change.ts +18 -8
- package/src/test-utils/build-mock-file-item-change.ts +3 -1
- package/src/test-utils/build-mock-new-id.ts +12 -0
- package/src/test-utils/build-mock-note-change.ts +18 -0
- package/src/test-utils/build-mock-pause-change.ts +2 -10
- package/src/test-utils/build-mock-pull-request-change.ts +19 -9
- package/src/test-utils/{build-mock-link-change.ts → build-mock-relation-change.ts} +6 -6
- package/src/test-utils/build-mock-running-reading.ts +19 -0
- package/src/test-utils/build-mock-settle-change.ts +18 -6
- package/src/test-utils/build-mock-start-change.ts +13 -6
- package/src/test-utils/claim-store-attempt-reader-cases.ts +163 -133
- package/src/test-utils/claim-store-claim-cases.ts +168 -85
- package/src/test-utils/claim-store-close-cases.ts +95 -0
- package/src/test-utils/claim-store-contract.ts +12 -2
- package/src/test-utils/claim-store-copy-cases.ts +100 -0
- package/src/test-utils/claim-store-exclusive-cases.ts +65 -19
- package/src/test-utils/claim-store-guard-cases.ts +92 -82
- package/src/test-utils/claim-store-item-reader-cases.ts +291 -77
- package/src/test-utils/claim-store-outbox-cases.ts +281 -0
- package/src/test-utils/claim-store-race-cases.ts +150 -0
- package/src/test-utils/claim-store-rollback-cases.ts +50 -50
- package/src/test-utils/claim-store-seat-cases.ts +270 -0
- package/src/test-utils/claim-store-session-cases.ts +289 -0
- package/src/test-utils/collect-memory-limit-fills.ts +15 -0
- package/src/test-utils/compare-text.ts +8 -0
- package/src/test-utils/create-fake-backoff.ts +16 -0
- package/src/test-utils/create-fake-clock.ts +20 -0
- package/src/test-utils/create-fake-fact-sink.ts +74 -0
- package/src/test-utils/create-fake-forge.ts +117 -0
- package/src/test-utils/create-fake-worker.ts +303 -0
- package/src/test-utils/create-memory-claim-store.ts +73 -484
- package/src/test-utils/create-test-dispatch.ts +597 -0
- package/src/test-utils/forge-contract.ts +171 -0
- package/src/test-utils/is-same-held-seat.ts +11 -0
- package/src/test-utils/types.ts +14 -2
- package/src/test-utils/worker-contract.ts +192 -0
- package/src/timeouts.ts +17 -0
- package/src/types.ts +32 -0
- package/dist/test-utils/claim-store-pool-cases.d.ts +0 -2
- package/src/test-utils/claim-store-pool-cases.ts +0 -178
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { setImmediate } from 'node:timers/promises';
|
|
2
2
|
import { brandSchemas } from '@boxxy/model';
|
|
3
|
-
import {
|
|
3
|
+
import { buildMockItemRules } from '@boxxy/model/test-utils/build-mock-item-rules';
|
|
4
|
+
import { buildMockV1ItemRow } from '@boxxy/model/test-utils/build-mock-v1-item-row';
|
|
4
5
|
import { buildMockFileItemChange } from './build-mock-file-item-change.ts';
|
|
5
6
|
import type { ClaimStoreCase } from './types.ts';
|
|
6
7
|
|
|
@@ -38,7 +39,7 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
38
39
|
[
|
|
39
40
|
'#exclusive leaves the state as it was when work throws',
|
|
40
41
|
async (store) => {
|
|
41
|
-
const item =
|
|
42
|
+
const item = buildMockV1ItemRow();
|
|
42
43
|
|
|
43
44
|
const writing = store.exclusive(async (transaction) => {
|
|
44
45
|
await transaction.applyChange(buildMockFileItemChange(item));
|
|
@@ -49,7 +50,7 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
49
50
|
await writing.catch(() => null);
|
|
50
51
|
|
|
51
52
|
const snapshot: unknown = await store.read((transaction) =>
|
|
52
|
-
transaction.readSnapshot(brandSchemas.instant.parse(5000),
|
|
53
|
+
transaction.readSnapshot(brandSchemas.instant.parse(5000), buildMockItemRules()),
|
|
53
54
|
);
|
|
54
55
|
|
|
55
56
|
return {
|
|
@@ -57,9 +58,10 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
57
58
|
expected: {
|
|
58
59
|
storeVersion: 0,
|
|
59
60
|
items: [],
|
|
60
|
-
|
|
61
|
+
relations: [],
|
|
61
62
|
levers: [],
|
|
62
|
-
|
|
63
|
+
limits: [],
|
|
64
|
+
wakes: [],
|
|
63
65
|
},
|
|
64
66
|
};
|
|
65
67
|
},
|
|
@@ -82,7 +84,7 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
82
84
|
[
|
|
83
85
|
'#exclusive runs a later call after an earlier call throws',
|
|
84
86
|
async (store) => {
|
|
85
|
-
const item =
|
|
87
|
+
const item = buildMockV1ItemRow();
|
|
86
88
|
|
|
87
89
|
const failing = store.exclusive(() => {
|
|
88
90
|
throw new Error('the work failed');
|
|
@@ -95,7 +97,7 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
95
97
|
);
|
|
96
98
|
|
|
97
99
|
const read = await store.read((transaction) =>
|
|
98
|
-
transaction.readItem(item.id, brandSchemas.instant.parse(5000),
|
|
100
|
+
transaction.readItem(item.id, brandSchemas.instant.parse(5000), buildMockItemRules()),
|
|
99
101
|
);
|
|
100
102
|
|
|
101
103
|
return { received: read?.id, expected: item.id };
|
|
@@ -104,8 +106,8 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
104
106
|
[
|
|
105
107
|
'#read during a running exclusive call sees the last committed state',
|
|
106
108
|
async (store) => {
|
|
107
|
-
const committed =
|
|
108
|
-
const pending =
|
|
109
|
+
const committed = buildMockV1ItemRow({ filedAt: brandSchemas.instant.parse(1000) });
|
|
110
|
+
const pending = buildMockV1ItemRow({ filedAt: brandSchemas.instant.parse(2000) });
|
|
109
111
|
const gate = Promise.withResolvers<void>();
|
|
110
112
|
const written = Promise.withResolvers<void>();
|
|
111
113
|
|
|
@@ -124,7 +126,7 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
124
126
|
await written.promise;
|
|
125
127
|
|
|
126
128
|
const seen = await store.read((transaction) =>
|
|
127
|
-
transaction.listItems({}, brandSchemas.instant.parse(5000),
|
|
129
|
+
transaction.listItems({}, brandSchemas.instant.parse(5000), buildMockItemRules()),
|
|
128
130
|
);
|
|
129
131
|
|
|
130
132
|
gate.resolve();
|
|
@@ -137,19 +139,27 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
137
139
|
[
|
|
138
140
|
'#read keeps one snapshot across a commit made during the call',
|
|
139
141
|
async (store) => {
|
|
140
|
-
const committed =
|
|
141
|
-
const later =
|
|
142
|
+
const committed = buildMockV1ItemRow({ filedAt: brandSchemas.instant.parse(1000) });
|
|
143
|
+
const later = buildMockV1ItemRow({ filedAt: brandSchemas.instant.parse(2000) });
|
|
142
144
|
|
|
143
145
|
await store.exclusive((transaction) =>
|
|
144
146
|
transaction.applyChange(buildMockFileItemChange(committed)),
|
|
145
147
|
);
|
|
146
148
|
|
|
147
149
|
const seen: unknown = await store.read(async (transaction) => {
|
|
148
|
-
const before = await transaction.listItems(
|
|
150
|
+
const before = await transaction.listItems(
|
|
151
|
+
{},
|
|
152
|
+
brandSchemas.instant.parse(5000),
|
|
153
|
+
buildMockItemRules(),
|
|
154
|
+
);
|
|
149
155
|
|
|
150
156
|
await store.exclusive((writer) => writer.applyChange(buildMockFileItemChange(later)));
|
|
151
157
|
|
|
152
|
-
const after = await transaction.listItems(
|
|
158
|
+
const after = await transaction.listItems(
|
|
159
|
+
{},
|
|
160
|
+
brandSchemas.instant.parse(5000),
|
|
161
|
+
buildMockItemRules(),
|
|
162
|
+
);
|
|
153
163
|
|
|
154
164
|
return { before: before.map((item) => item.id), after: after.map((item) => item.id) };
|
|
155
165
|
});
|
|
@@ -157,10 +167,44 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
157
167
|
return { received: seen, expected: { before: [committed.id], after: [committed.id] } };
|
|
158
168
|
},
|
|
159
169
|
],
|
|
170
|
+
[
|
|
171
|
+
'#read rejects with the error work throws',
|
|
172
|
+
async (store) => {
|
|
173
|
+
const reading = store.read(() => {
|
|
174
|
+
throw new Error('the read failed');
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const settled = await reading.then(
|
|
178
|
+
() => 'resolved',
|
|
179
|
+
(error: unknown) => error,
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
return { received: settled, expected: new Error('the read failed') };
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
[
|
|
186
|
+
'#read runs a read started inside another read',
|
|
187
|
+
async (store) => {
|
|
188
|
+
const item = buildMockV1ItemRow();
|
|
189
|
+
|
|
190
|
+
await store.exclusive((transaction) =>
|
|
191
|
+
transaction.applyChange(buildMockFileItemChange(item)),
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
const seen = await store.read(() =>
|
|
195
|
+
store.read((transaction) =>
|
|
196
|
+
transaction.readItem(item.id, brandSchemas.instant.parse(5000), buildMockItemRules()),
|
|
197
|
+
),
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
return { received: seen?.id, expected: item.id };
|
|
201
|
+
},
|
|
202
|
+
],
|
|
160
203
|
[
|
|
161
204
|
'#applyChange writes the rows and the outbox facts of a change',
|
|
162
205
|
async (store) => {
|
|
163
|
-
const item =
|
|
206
|
+
const item = buildMockV1ItemRow({ filedAt: brandSchemas.instant.parse(1000) });
|
|
207
|
+
const { keptSession: _keptSession, ...filed } = item;
|
|
164
208
|
const change = buildMockFileItemChange(item);
|
|
165
209
|
|
|
166
210
|
await store.exclusive((transaction) => transaction.applyChange(change));
|
|
@@ -177,21 +221,23 @@ export const claimStoreExclusiveCases: readonly ClaimStoreCase[] = [
|
|
|
177
221
|
entity: `boxxy:item:${item.id}`,
|
|
178
222
|
actor: 'boxxy:owner:local',
|
|
179
223
|
at: 1000,
|
|
180
|
-
payload:
|
|
224
|
+
payload: filed,
|
|
181
225
|
sentAt: null,
|
|
226
|
+
parkedAt: null,
|
|
227
|
+
parkedReason: null,
|
|
182
228
|
},
|
|
183
229
|
],
|
|
184
230
|
};
|
|
185
231
|
},
|
|
186
232
|
],
|
|
187
233
|
[
|
|
188
|
-
'#applyChange returns applied
|
|
234
|
+
'#applyChange returns applied for a change that it writes',
|
|
189
235
|
async (store) => {
|
|
190
|
-
const change = buildMockFileItemChange(
|
|
236
|
+
const change = buildMockFileItemChange(buildMockV1ItemRow());
|
|
191
237
|
|
|
192
238
|
const result = await store.exclusive((transaction) => transaction.applyChange(change));
|
|
193
239
|
|
|
194
|
-
return { received: result, expected: { kind: 'applied'
|
|
240
|
+
return { received: result, expected: { kind: 'applied' } };
|
|
195
241
|
},
|
|
196
242
|
],
|
|
197
243
|
];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { brandSchemas } from '@boxxy/model';
|
|
2
|
-
import { buildMockAttemptRow } from '@boxxy/model/test-utils/build-mock-attempt-row';
|
|
3
2
|
import { buildMockFactId } from '@boxxy/model/test-utils/build-mock-fact-id';
|
|
4
|
-
import {
|
|
3
|
+
import { buildMockItemRules } from '@boxxy/model/test-utils/build-mock-item-rules';
|
|
4
|
+
import { buildMockV1AttemptRow } from '@boxxy/model/test-utils/build-mock-v1-attempt-row';
|
|
5
|
+
import { buildMockV1ItemRow } from '@boxxy/model/test-utils/build-mock-v1-item-row';
|
|
5
6
|
import { buildMockBindChange } from './build-mock-bind-change.ts';
|
|
6
7
|
import { buildMockClaimChange } from './build-mock-claim-change.ts';
|
|
7
8
|
import { buildMockFileItemChange } from './build-mock-file-item-change.ts';
|
|
@@ -11,81 +12,83 @@ import type { ClaimStoreCase } from './types.ts';
|
|
|
11
12
|
|
|
12
13
|
export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
13
14
|
[
|
|
14
|
-
'#applyChange returns stale-generation for a settle under an old
|
|
15
|
+
'#applyChange returns stale-generation and keeps the seats for a settle under an old hold gen',
|
|
15
16
|
async (store) => {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const holder = buildMockAttemptRow({ item: second.id, state: 'starting' });
|
|
17
|
+
const workers = brandSchemas.limitName.parse('workers');
|
|
18
|
+
const item = buildMockV1ItemRow();
|
|
19
|
+
const attempt = buildMockV1AttemptRow({ item: item.id, state: 'starting', holdGen: 2 });
|
|
20
20
|
|
|
21
21
|
await store.exclusive(async (transaction) => {
|
|
22
|
-
await transaction.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
await transaction.applyChange(buildMockClaimChange(settled));
|
|
26
|
-
|
|
27
|
-
await transaction.applyChange(
|
|
28
|
-
buildMockSettleChange({
|
|
29
|
-
attempt: { ...settled, slot: 1, slotGen: 1 },
|
|
30
|
-
state: 'succeeded',
|
|
31
|
-
}),
|
|
22
|
+
await transaction.syncLimits(
|
|
23
|
+
[{ name: workers, max: 1, counts: {} }],
|
|
24
|
+
brandSchemas.instant.parse(500),
|
|
32
25
|
);
|
|
33
26
|
|
|
34
|
-
await transaction.applyChange(
|
|
27
|
+
await transaction.applyChange(buildMockFileItemChange(item));
|
|
28
|
+
await transaction.applyChange(buildMockClaimChange(attempt, [workers]));
|
|
35
29
|
});
|
|
36
30
|
|
|
37
31
|
const result = await store.exclusive((transaction) =>
|
|
38
32
|
transaction.applyChange(
|
|
39
|
-
buildMockSettleChange({ attempt: { ...
|
|
33
|
+
buildMockSettleChange({ attempt: { ...attempt, holdGen: 1 }, state: 'failed' }),
|
|
40
34
|
),
|
|
41
35
|
);
|
|
42
36
|
|
|
43
|
-
const
|
|
37
|
+
const seats = await store.read((transaction) => transaction.listLimitSeats());
|
|
44
38
|
|
|
45
39
|
return {
|
|
46
|
-
received: { result,
|
|
40
|
+
received: { result, seats },
|
|
47
41
|
expected: {
|
|
48
42
|
result: { kind: 'stale-generation' },
|
|
49
|
-
|
|
43
|
+
seats: [
|
|
44
|
+
{
|
|
45
|
+
limit: 'workers',
|
|
46
|
+
attempt: attempt.id,
|
|
47
|
+
holdGen: 2,
|
|
48
|
+
overCap: false,
|
|
49
|
+
takenAt: attempt.claimedAt,
|
|
50
|
+
releasedAt: null,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
50
53
|
},
|
|
51
54
|
};
|
|
52
55
|
},
|
|
53
56
|
],
|
|
54
57
|
[
|
|
55
|
-
'#applyChange releases
|
|
58
|
+
'#applyChange releases the lease and the seats of a settle under the live generations',
|
|
56
59
|
async (store) => {
|
|
57
|
-
const
|
|
58
|
-
const
|
|
60
|
+
const workers = brandSchemas.limitName.parse('workers');
|
|
61
|
+
const item = buildMockV1ItemRow();
|
|
62
|
+
const attempt = buildMockV1AttemptRow({ item: item.id, state: 'starting' });
|
|
59
63
|
|
|
60
64
|
await store.exclusive(async (transaction) => {
|
|
61
|
-
await transaction.
|
|
65
|
+
await transaction.syncLimits(
|
|
66
|
+
[{ name: workers, max: 1, counts: {} }],
|
|
67
|
+
brandSchemas.instant.parse(500),
|
|
68
|
+
);
|
|
69
|
+
|
|
62
70
|
await transaction.applyChange(buildMockFileItemChange(item));
|
|
63
|
-
await transaction.applyChange(buildMockClaimChange(attempt));
|
|
71
|
+
await transaction.applyChange(buildMockClaimChange(attempt, [workers]));
|
|
64
72
|
});
|
|
65
73
|
|
|
66
74
|
const result = await store.exclusive((transaction) =>
|
|
67
|
-
transaction.applyChange(
|
|
68
|
-
buildMockSettleChange({
|
|
69
|
-
attempt: { ...attempt, slot: 1, slotGen: 1 },
|
|
70
|
-
state: 'succeeded',
|
|
71
|
-
}),
|
|
72
|
-
),
|
|
75
|
+
transaction.applyChange(buildMockSettleChange({ attempt, state: 'succeeded' })),
|
|
73
76
|
);
|
|
74
77
|
|
|
75
78
|
const snapshot = await store.read((transaction) =>
|
|
76
|
-
transaction.readSnapshot(brandSchemas.instant.parse(5000),
|
|
79
|
+
transaction.readSnapshot(brandSchemas.instant.parse(5000), buildMockItemRules()),
|
|
77
80
|
);
|
|
78
81
|
|
|
79
82
|
return {
|
|
80
83
|
received: {
|
|
81
84
|
result,
|
|
82
|
-
|
|
85
|
+
limits: snapshot.limits,
|
|
83
86
|
derived: snapshot.items[0]?.derived,
|
|
84
87
|
},
|
|
85
88
|
expected: {
|
|
86
|
-
result: { kind: 'applied'
|
|
87
|
-
|
|
88
|
-
derived: { state: 'waiting', reason: 'no
|
|
89
|
+
result: { kind: 'applied' },
|
|
90
|
+
limits: [{ name: 'workers', max: 1, counts: {}, held: 0 }],
|
|
91
|
+
derived: { state: 'waiting', reason: 'no pull request linked' },
|
|
89
92
|
},
|
|
90
93
|
};
|
|
91
94
|
},
|
|
@@ -93,11 +96,10 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
93
96
|
[
|
|
94
97
|
'#applyChange returns stale-generation and writes no fact under a stale lease generation',
|
|
95
98
|
async (store) => {
|
|
96
|
-
const item =
|
|
97
|
-
const attempt =
|
|
99
|
+
const item = buildMockV1ItemRow();
|
|
100
|
+
const attempt = buildMockV1AttemptRow({ item: item.id, state: 'starting' });
|
|
98
101
|
|
|
99
102
|
await store.exclusive(async (transaction) => {
|
|
100
|
-
await transaction.syncPoolSlots([{ name: attempt.pool, slots: 1 }]);
|
|
101
103
|
await transaction.applyChange(buildMockFileItemChange(item));
|
|
102
104
|
await transaction.applyChange(buildMockClaimChange(attempt));
|
|
103
105
|
});
|
|
@@ -125,17 +127,13 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
125
127
|
[
|
|
126
128
|
'#applyChange returns stale-generation under a released lease',
|
|
127
129
|
async (store) => {
|
|
128
|
-
const item =
|
|
129
|
-
const attempt =
|
|
130
|
+
const item = buildMockV1ItemRow();
|
|
131
|
+
const attempt = buildMockV1AttemptRow({ item: item.id, state: 'starting' });
|
|
130
132
|
|
|
131
133
|
await store.exclusive(async (transaction) => {
|
|
132
|
-
await transaction.syncPoolSlots([{ name: attempt.pool, slots: 1 }]);
|
|
133
134
|
await transaction.applyChange(buildMockFileItemChange(item));
|
|
134
135
|
await transaction.applyChange(buildMockClaimChange(attempt));
|
|
135
|
-
|
|
136
|
-
await transaction.applyChange(
|
|
137
|
-
buildMockSettleChange({ attempt: { ...attempt, slot: 1, slotGen: 1 }, state: 'failed' }),
|
|
138
|
-
);
|
|
136
|
+
await transaction.applyChange(buildMockSettleChange({ attempt, state: 'failed' }));
|
|
139
137
|
});
|
|
140
138
|
|
|
141
139
|
const result = await store.exclusive((transaction) =>
|
|
@@ -148,11 +146,10 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
148
146
|
[
|
|
149
147
|
'#applyChange applies a change under the live lease generation',
|
|
150
148
|
async (store) => {
|
|
151
|
-
const item =
|
|
152
|
-
const attempt =
|
|
149
|
+
const item = buildMockV1ItemRow();
|
|
150
|
+
const attempt = buildMockV1AttemptRow({ item: item.id, state: 'starting' });
|
|
153
151
|
|
|
154
152
|
await store.exclusive(async (transaction) => {
|
|
155
|
-
await transaction.syncPoolSlots([{ name: attempt.pool, slots: 1 }]);
|
|
156
153
|
await transaction.applyChange(buildMockFileItemChange(item));
|
|
157
154
|
await transaction.applyChange(buildMockClaimChange(attempt));
|
|
158
155
|
await transaction.applyChange(buildMockStartChange(attempt));
|
|
@@ -166,7 +163,7 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
166
163
|
[
|
|
167
164
|
'#applyChange returns guard-mismatch and writes nothing when an expect fails',
|
|
168
165
|
async (store) => {
|
|
169
|
-
const item =
|
|
166
|
+
const item = buildMockV1ItemRow();
|
|
170
167
|
|
|
171
168
|
await store.exclusive((transaction) =>
|
|
172
169
|
transaction.applyChange(buildMockFileItemChange(item)),
|
|
@@ -197,7 +194,7 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
197
194
|
type: 'boxxy.item.closed',
|
|
198
195
|
entity: `boxxy:item:${item.id}`,
|
|
199
196
|
actor: 'boxxy:owner:local',
|
|
200
|
-
payload: { reason: 'done by hand' },
|
|
197
|
+
payload: { reason: 'done by hand', byAttempt: null, ended: [] },
|
|
201
198
|
},
|
|
202
199
|
],
|
|
203
200
|
}),
|
|
@@ -207,7 +204,7 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
207
204
|
const read = await transaction.readItem(
|
|
208
205
|
item.id,
|
|
209
206
|
brandSchemas.instant.parse(5000),
|
|
210
|
-
|
|
207
|
+
buildMockItemRules(),
|
|
211
208
|
);
|
|
212
209
|
|
|
213
210
|
const facts = await transaction.readUnsentFacts(10);
|
|
@@ -219,7 +216,14 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
219
216
|
received: { result, state },
|
|
220
217
|
expected: {
|
|
221
218
|
result: { kind: 'guard-mismatch', table: 'items', key: { id: item.id } },
|
|
222
|
-
state: {
|
|
219
|
+
state: {
|
|
220
|
+
item: {
|
|
221
|
+
...item,
|
|
222
|
+
derived: { state: 'ready' },
|
|
223
|
+
position: { kind: 'phase', phase: 'build', round: 1 },
|
|
224
|
+
},
|
|
225
|
+
facts: 1,
|
|
226
|
+
},
|
|
223
227
|
},
|
|
224
228
|
};
|
|
225
229
|
},
|
|
@@ -227,7 +231,7 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
227
231
|
[
|
|
228
232
|
'#applyChange returns guard-mismatch for an update that finds no row',
|
|
229
233
|
async (store) => {
|
|
230
|
-
const item =
|
|
234
|
+
const item = buildMockV1ItemRow();
|
|
231
235
|
|
|
232
236
|
const result = await store.exclusive((transaction) =>
|
|
233
237
|
transaction.applyChange({
|
|
@@ -247,7 +251,7 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
247
251
|
type: 'boxxy.item.edited',
|
|
248
252
|
entity: `boxxy:item:${item.id}`,
|
|
249
253
|
actor: 'boxxy:owner:local',
|
|
250
|
-
payload: { title: 'Mend the gate' },
|
|
254
|
+
payload: { title: 'Mend the gate', byAttempt: null },
|
|
251
255
|
},
|
|
252
256
|
],
|
|
253
257
|
}),
|
|
@@ -272,7 +276,7 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
272
276
|
evidence: [],
|
|
273
277
|
};
|
|
274
278
|
|
|
275
|
-
const item =
|
|
279
|
+
const item = buildMockV1ItemRow({ acceptance: [criterion] });
|
|
276
280
|
|
|
277
281
|
await store.exclusive((transaction) =>
|
|
278
282
|
transaction.applyChange(buildMockFileItemChange(item)),
|
|
@@ -300,24 +304,23 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
300
304
|
type: 'boxxy.item.edited',
|
|
301
305
|
entity: `boxxy:item:${item.id}`,
|
|
302
306
|
actor: 'boxxy:owner:local',
|
|
303
|
-
payload: { title: 'Mend the gate' },
|
|
307
|
+
payload: { title: 'Mend the gate', byAttempt: null },
|
|
304
308
|
},
|
|
305
309
|
],
|
|
306
310
|
}),
|
|
307
311
|
);
|
|
308
312
|
|
|
309
|
-
return { received: result, expected: { kind: 'applied'
|
|
313
|
+
return { received: result, expected: { kind: 'applied' } };
|
|
310
314
|
},
|
|
311
315
|
],
|
|
312
316
|
[
|
|
313
317
|
'#findAttemptByAgentSession returns the attempt that holds an agent session id',
|
|
314
318
|
async (store) => {
|
|
315
|
-
const item =
|
|
316
|
-
const attempt =
|
|
319
|
+
const item = buildMockV1ItemRow();
|
|
320
|
+
const attempt = buildMockV1AttemptRow({ item: item.id, state: 'starting' });
|
|
317
321
|
const agentSession = brandSchemas.agentSessionId.parse('agent-session-1');
|
|
318
322
|
|
|
319
323
|
await store.exclusive(async (transaction) => {
|
|
320
|
-
await transaction.syncPoolSlots([{ name: attempt.pool, slots: 1 }]);
|
|
321
324
|
await transaction.applyChange(buildMockFileItemChange(item));
|
|
322
325
|
await transaction.applyChange(buildMockClaimChange(attempt));
|
|
323
326
|
await transaction.applyChange(buildMockBindChange({ attempt, agentSession }));
|
|
@@ -341,33 +344,40 @@ export const claimStoreGuardCases: readonly ClaimStoreCase[] = [
|
|
|
341
344
|
},
|
|
342
345
|
],
|
|
343
346
|
[
|
|
344
|
-
'#
|
|
347
|
+
'#findAttemptByAgentSession returns the later of two attempts bound to one agent session',
|
|
345
348
|
async (store) => {
|
|
346
|
-
const
|
|
347
|
-
const second = buildMockItemRow();
|
|
348
|
-
const holder = buildMockAttemptRow({ item: first.id, state: 'starting' });
|
|
349
|
-
const other = buildMockAttemptRow({ item: second.id, state: 'starting' });
|
|
349
|
+
const item = buildMockV1ItemRow();
|
|
350
350
|
const agentSession = brandSchemas.agentSessionId.parse('agent-session-1');
|
|
351
351
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
await transaction.applyChange(buildMockClaimChange(holder));
|
|
357
|
-
await transaction.applyChange(buildMockClaimChange(other));
|
|
358
|
-
await transaction.applyChange(buildMockBindChange({ attempt: holder, agentSession }));
|
|
352
|
+
const earlier = buildMockV1AttemptRow({
|
|
353
|
+
item: item.id,
|
|
354
|
+
state: 'starting',
|
|
355
|
+
claimedAt: brandSchemas.instant.parse(1000),
|
|
359
356
|
});
|
|
360
357
|
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
358
|
+
const later = buildMockV1AttemptRow({
|
|
359
|
+
item: item.id,
|
|
360
|
+
state: 'starting',
|
|
361
|
+
number: 2,
|
|
362
|
+
leaseGen: 2,
|
|
363
|
+
atcSession: earlier.atcSession,
|
|
364
|
+
claimedAt: brandSchemas.instant.parse(4000),
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
await store.exclusive(async (transaction) => {
|
|
368
|
+
await transaction.applyChange(buildMockFileItemChange(item));
|
|
369
|
+
await transaction.applyChange(buildMockClaimChange(earlier));
|
|
370
|
+
await transaction.applyChange(buildMockBindChange({ attempt: earlier, agentSession }));
|
|
371
|
+
await transaction.applyChange(buildMockSettleChange({ attempt: earlier, state: 'failed' }));
|
|
372
|
+
await transaction.applyChange(buildMockClaimChange(later));
|
|
373
|
+
await transaction.applyChange(buildMockBindChange({ attempt: later, agentSession }));
|
|
374
|
+
});
|
|
364
375
|
|
|
365
|
-
const
|
|
366
|
-
()
|
|
367
|
-
() => 'thrown',
|
|
376
|
+
const found = await store.read((transaction) =>
|
|
377
|
+
transaction.findAttemptByAgentSession(agentSession),
|
|
368
378
|
);
|
|
369
379
|
|
|
370
|
-
return { received:
|
|
380
|
+
return { received: found, expected: later.id };
|
|
371
381
|
},
|
|
372
382
|
],
|
|
373
383
|
];
|