fix(core): prevent shell eviction loop (#43650)
This commit is contained in:
@@ -148,10 +148,10 @@ const layer = () =>
|
||||
|
||||
const removeSession = Effect.fnUntraced(function* (id: Shell.ID) {
|
||||
const session = sessions.get(id)
|
||||
if (!session) return
|
||||
sessions.delete(id)
|
||||
const index = exitOrder.indexOf(id)
|
||||
if (index !== -1) exitOrder.splice(index, 1)
|
||||
if (!session) return
|
||||
sessions.delete(id)
|
||||
if (session.timeoutFiber) yield* Fiber.interrupt(session.timeoutFiber)
|
||||
// Unblock any wait still pending when the command is removed before it terminated.
|
||||
yield* Deferred.fail(session.done, new NotFoundError({ id }))
|
||||
|
||||
@@ -856,6 +856,30 @@ describe("ShellTool", () => {
|
||||
{ timeout: 15_000 },
|
||||
)
|
||||
|
||||
it.live("does not retain removed running shells in exit order", () =>
|
||||
Effect.acquireUseRelease(
|
||||
Effect.promise(() => tmpdir()),
|
||||
(tmp) =>
|
||||
withSession(tmp.path, () =>
|
||||
Effect.gen(function* () {
|
||||
const shell = yield* Shell.Service
|
||||
yield* Effect.forEach(Array.from({ length: 26 }), () =>
|
||||
Effect.gen(function* () {
|
||||
const info = yield* shell.create({ command: idleCommand, timeout: 0 })
|
||||
yield* shell.remove(info.id)
|
||||
yield* Effect.sleep(Duration.millis(10))
|
||||
}),
|
||||
)
|
||||
|
||||
const info = yield* shell.create({ command: helloCommand, timeout: 0 })
|
||||
const settled = yield* shell.wait(info.id).pipe(Effect.timeoutOption(Duration.seconds(2)))
|
||||
expect(settled._tag).toBe("Some")
|
||||
}),
|
||||
),
|
||||
(tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]().then(() => undefined)),
|
||||
),
|
||||
)
|
||||
|
||||
if (!isWindows) {
|
||||
it.live("settles a shell terminated by an external signal", () =>
|
||||
Effect.acquireUseRelease(
|
||||
|
||||
Reference in New Issue
Block a user