Skip to content

Commit 32ed269

Browse files
committed
test(balance-worker): cover consumer-first writer apply
1 parent 7ffd959 commit 32ed269

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

apps/balance-worker/src/writer/committedTrackOutcomeAppender.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { TrackOutcome } from "@autumn/balance-engine";
22

3+
/** May be thrown only when the appender proves that no outcome was committed. */
34
export class TrackOutcomeBatchNotCommittedError extends Error {
45
constructor({ cause }: { cause: unknown }) {
56
super("Track outcome batch was not committed", { cause });
@@ -8,6 +9,7 @@ export class TrackOutcomeBatchNotCommittedError extends Error {
89
}
910

1011
export type CommittedTrackOutcomeAppender = {
12+
/** Atomically commits all outcomes contiguously and returns the first record's offset. */
1113
appendCommitted({
1214
topic,
1315
partition,

apps/balance-worker/tests/unit/writer/partition-track-writer.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,46 @@ describe("partition track writer", () => {
319319
}
320320
});
321321

322+
test("returns its receipt when the consumer applies the outcome first", async () => {
323+
const fixture = createFixture();
324+
try {
325+
const appender = new ControlledCommittedAppender();
326+
const writer = createPartitionTrackWriter({
327+
topic,
328+
partition,
329+
stateStore: fixture.store,
330+
appender,
331+
limits: defaultLimits,
332+
});
333+
const decisionPromise = writer.submitTrack({
334+
command: createCommand({ commandId: "cmd_1" }),
335+
});
336+
337+
await waitForBatch();
338+
const outcome = appender.batches[0]?.[0];
339+
if (!outcome) throw new Error("Expected an appended track outcome");
340+
expect(
341+
fixture.store.applyDurableTrackOutcome({
342+
position: { topic, partition, offset: 0n },
343+
outcome,
344+
}),
345+
).toMatchObject({ kind: "applied", nextOffset: 1n });
346+
347+
appender.resolve();
348+
await expect(decisionPromise).resolves.toEqual({ kind: "new", outcome });
349+
expect(
350+
readBalance({ store: fixture.store, identity: firstIdentity }),
351+
).toEqual({
352+
balance: 5,
353+
usage: 5,
354+
revision: 1,
355+
});
356+
expect(fixture.store.readNextOffset({ topic, partition })).toBe(1n);
357+
} finally {
358+
closeFixture(fixture);
359+
}
360+
});
361+
322362
test("projects commands that arrive while an earlier batch is in flight", async () => {
323363
const fixture = createFixture();
324364
try {

0 commit comments

Comments
 (0)