mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-22 04:13:26 +00:00
fix(core): coalesce queued compactions (#43292)
This commit is contained in:
parent
511b4556a2
commit
5ff6bb87cf
2 changed files with 39 additions and 10 deletions
|
|
@ -180,13 +180,27 @@ export const admitCompaction = Effect.fn("SessionInbox.admitCompaction")(functio
|
|||
bus: Bus.Interface,
|
||||
input: { readonly id: SessionMessage.ID; readonly sessionID: SessionSchema.ID; readonly delivery: Delivery },
|
||||
) {
|
||||
const admitted = yield* admit(db, bus, {
|
||||
id: input.id,
|
||||
sessionID: input.sessionID,
|
||||
item: Item.make({ type: "compaction", payload: {}, delivery: input.delivery }),
|
||||
})
|
||||
if (admitted.type === "compaction") return admitted
|
||||
return yield* Effect.die(new LifecycleConflict({ id: input.id }))
|
||||
return yield* serialized(
|
||||
input.sessionID,
|
||||
Effect.gen(function* () {
|
||||
const exact = yield* find(db, input.id)
|
||||
if (exact) {
|
||||
if (exact.type === "compaction" && exact.sessionID === input.sessionID) return exact
|
||||
return yield* Effect.die(new LifecycleConflict({ id: input.id }))
|
||||
}
|
||||
if (yield* promotedFromMessage(db, input.sessionID, input.id, input.delivery))
|
||||
return yield* Effect.die(new LifecycleConflict({ id: input.id }))
|
||||
const pending = (yield* list(db, input.sessionID)).find((item) => item.type === "compaction")
|
||||
if (pending) return pending
|
||||
const admitted = yield* admit(db, bus, {
|
||||
id: input.id,
|
||||
sessionID: input.sessionID,
|
||||
item: Item.make({ type: "compaction", payload: {}, delivery: input.delivery }),
|
||||
})
|
||||
if (admitted.type === "compaction") return admitted
|
||||
return yield* Effect.die(new LifecycleConflict({ id: input.id }))
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
export const projectAdmitted = Effect.fn("SessionInbox.projectAdmitted")(function* (
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ const it = testEffect(
|
|||
)
|
||||
|
||||
describe("Session.compact", () => {
|
||||
it.effect("durably stacks manual compaction", () =>
|
||||
it.effect("durably coalesces manual compaction", () =>
|
||||
Effect.gen(function* () {
|
||||
requests = []
|
||||
const session = yield* Session.Service
|
||||
|
|
@ -102,11 +102,10 @@ describe("Session.compact", () => {
|
|||
const first = yield* session.compact({ sessionID: created.id })
|
||||
const second = yield* session.compact({ sessionID: created.id })
|
||||
|
||||
expect(second.id).not.toBe(first.id)
|
||||
expect(second.id).toBe(first.id)
|
||||
expect(requests).toHaveLength(0)
|
||||
expect(yield* session.inbox(created.id)).toEqual([
|
||||
expect.objectContaining({ id: first.id, type: "compaction", delivery: "queue" }),
|
||||
expect.objectContaining({ id: second.id, type: "compaction", delivery: "queue" }),
|
||||
])
|
||||
expect((yield* session.context(created.id)).find((message) => message.id === first.id)).toBeUndefined()
|
||||
|
||||
|
|
@ -115,4 +114,20 @@ describe("Session.compact", () => {
|
|||
expect(steer).toMatchObject({ type: "compaction", delivery: "steer" })
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("coalesces concurrent manual compaction", () =>
|
||||
Effect.gen(function* () {
|
||||
const session = yield* Session.Service
|
||||
const created = yield* session.create({ location })
|
||||
const admitted = yield* Effect.all(
|
||||
[SessionMessage.ID.create(), SessionMessage.ID.create()].map((id) =>
|
||||
session.compact({ id, sessionID: created.id }),
|
||||
),
|
||||
{ concurrency: "unbounded" },
|
||||
)
|
||||
|
||||
expect(admitted[1]?.id).toBe(admitted[0]?.id)
|
||||
expect(yield* session.inbox(created.id)).toHaveLength(1)
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue