Upstream test/run.test.ts currently has these tests:
can halt itself
can halt itself between yield points
Both call yield* task.halt() from inside the task being halted.
That seems like a broken API pattern. halt() requests cancellation and waits for the task's teardown to finish. If the task itself is yielding on that drain, teardown cannot finish until the current generator unwinds. That's a self-join.
Minimal shape:
let task: Task<void> = run(function* () {
yield* sleep(0);
yield* task.halt();
});
await task;
I think self-cancel needs a request-only operation instead, e.g. task.requestHalt() / task.requestCancel(), with task.halt() kept as the external request-and-drain API.
If yield* task.halt() from inside the same task is intentionally unsupported, it would be useful for Effection to document that or reject it with a clear error instead of treating it as normal cancellation behavior.
Upstream
test/run.test.tscurrently has these tests:can halt itselfcan halt itself between yield pointsBoth call
yield* task.halt()from inside the task being halted.That seems like a broken API pattern.
halt()requests cancellation and waits for the task's teardown to finish. If the task itself is yielding on that drain, teardown cannot finish until the current generator unwinds. That's a self-join.Minimal shape:
I think self-cancel needs a request-only operation instead, e.g.
task.requestHalt()/task.requestCancel(), withtask.halt()kept as the external request-and-drain API.If
yield* task.halt()from inside the same task is intentionally unsupported, it would be useful for Effection to document that or reject it with a clear error instead of treating it as normal cancellation behavior.