Stop becomes Kill when the job ignores it
A background job that ignores SIGTERM could not be stopped from the UI at all. Stop sends SIGTERM to every pid holding the job's output file, and the second click sent the same signal again — task-restart.ts already said "that is what the second click is for", and it was not. Reported after a job hung in another chat. The button now escalates instead of a second button appearing beside it. Press Stop, and if the job is still running three seconds later the same control becomes Kill in the destructive tone, and sends SIGKILL. Escalating rather than always offering Kill, because a permanent Kill button is a second destructive control competing with the first, and people reach for it by default — losing the graceful shutdown that usually works. The delay is the same argument: a clean exit takes well under a second, so offering Kill at once teaches everyone to press it first. `?force=1` on the existing DELETE rather than a second route: same verb on the same thing, differing only in how hard it asks. The member path escalates too — one `kill -KILL` run as them, since fuser and the kill must both be their own identity. Stated in the button's own title rather than hidden: SIGKILL gives the process no chance to release a port or take its children with it. That is the right trade for a hang and the reason it is not offered first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -353,7 +353,10 @@ chatRouter.get('/tasks/:id', async (ctx) => {
|
||||
// say "please stop that" is a turn, and it only works while the agent is responsive.
|
||||
chatRouter.delete('/tasks/:id', async (ctx) => {
|
||||
const who = await chatIdentity(ctx.get('user'));
|
||||
const result = await stopBackgroundTask(who, ctx.req.param('id'));
|
||||
// `?force=1` escalates to SIGKILL. A query parameter rather than a second route: it is the same verb on
|
||||
// the same thing, differing only in how hard it asks.
|
||||
const force = ctx.req.query('force') === '1';
|
||||
const result = await stopBackgroundTask(who, ctx.req.param('id'), force);
|
||||
return ctx.json(result, result.stopped ? 200 : 400);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user