Worker drains on stop instead of re-queuing work; update.sh no longer waits for it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RNwtXPYqFu3oKaaXwYwNWW
This commit is contained in:
parent
9253c439ad
commit
93e1208cbc
3 changed files with 18 additions and 18 deletions
|
|
@ -13,7 +13,8 @@ ExecStart=/opt/node/bin/node --disable-warning=ExperimentalWarning /opt/together
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
# Restarting re-queues whatever was being verified.
|
# Restarting re-queues whatever was being verified.
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
TimeoutStopSec=15
|
# Stopping waits for the running verification or merge to finish.
|
||||||
|
TimeoutStopSec=1200
|
||||||
Environment=NODE_ENV=production
|
Environment=NODE_ENV=production
|
||||||
|
|
||||||
# Hardening. The process needs: its data dir, the docker socket, git.
|
# Hardening. The process needs: its data dir, the docker socket, git.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ set -eu
|
||||||
SRC=$(cd "${1:?usage: update.sh <source-dir>}" && pwd)
|
SRC=$(cd "${1:?usage: update.sh <source-dir>}" && pwd)
|
||||||
BASE=/opt/togetherdecomp-releases
|
BASE=/opt/togetherdecomp-releases
|
||||||
LINK=/opt/togetherdecomp
|
LINK=/opt/togetherdecomp
|
||||||
JOBS=/var/lib/togetherdecomp/jobs
|
|
||||||
NODE=/opt/node/bin/node
|
NODE=/opt/node/bin/node
|
||||||
REL="$BASE/$(date +%Y%m%d-%H%M%S)"
|
REL="$BASE/$(date +%Y%m%d-%H%M%S)"
|
||||||
|
|
||||||
|
|
@ -66,17 +65,10 @@ else
|
||||||
systemctl restart togetherdecomp.service
|
systemctl restart togetherdecomp.service
|
||||||
sleep 2
|
sleep 2
|
||||||
systemctl is-active --quiet togetherdecomp.service || { journalctl -u togetherdecomp -n 20 --no-pager; exit 1; }
|
systemctl is-active --quiet togetherdecomp.service || { journalctl -u togetherdecomp -n 20 --no-pager; exit 1; }
|
||||||
# A restart re-queues what the worker is doing. Remote checks are cheap to redo (the waiting agent
|
# The worker finishes its running verification, merge or check before it stops (no work is
|
||||||
# still gets its result); a batch verification or merge is waited for, up to 15 minutes.
|
# redone), then starts on the new release. That can take minutes, so don't wait for it here.
|
||||||
echo "== restarting the worker once no batch is being verified or merged"
|
echo "== the worker restarts once its running work is done"
|
||||||
waited=0
|
systemctl restart --no-block togetherdecomp-worker.service
|
||||||
while ls "$JOBS" 2>/dev/null | grep -qE '^(batch|merge)-' && [ "$waited" -lt 900 ]; do
|
|
||||||
sleep 5
|
|
||||||
waited=$((waited + 5))
|
|
||||||
done
|
|
||||||
systemctl restart togetherdecomp-worker.service
|
|
||||||
sleep 2
|
|
||||||
systemctl is-active --quiet togetherdecomp-worker.service || { journalctl -u togetherdecomp-worker -n 20 --no-pager; exit 1; }
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Keep the last three releases for a quick rollback (ln -sfn <release> /opt/togetherdecomp).
|
# Keep the last three releases for a quick rollback (ln -sfn <release> /opt/togetherdecomp).
|
||||||
|
|
|
||||||
|
|
@ -720,14 +720,21 @@ export async function startServer(dataDir, { role = 'all' } = {}) {
|
||||||
await new Promise((r) => server.listen(ctx.config.listen.port, ctx.config.listen.host, r));
|
await new Promise((r) => server.listen(ctx.config.listen.port, ctx.config.listen.host, r));
|
||||||
console.log(`clank together coordinator listening on http://${ctx.config.listen.host}:${ctx.config.listen.port} (public url ${ctx.config.publicUrl})`);
|
console.log(`clank together coordinator listening on http://${ctx.config.listen.host}:${ctx.config.listen.port} (public url ${ctx.config.publicUrl})`);
|
||||||
}
|
}
|
||||||
// Quick exit: requests still open (an agent waiting on a remote check can wait for minutes) are
|
// The web side exits quickly: requests still open (an agent waiting on a remote check can wait
|
||||||
// cut off after a moment; agents retry, and the work itself lives in the database and the worker.
|
// for minutes) are cut off after a moment; agents retry. The worker drains: it takes no new work
|
||||||
|
// and exits once its running verifications, merges and checks are done, so nothing is redone.
|
||||||
|
const busy = () => ctx.runsWorker && (ctx.verifier.running > 0 || ctx.merger.busy || ctx.checks.running > 0);
|
||||||
|
const exitWhenIdle = () => (busy() ? setTimeout(exitWhenIdle, 1000) : process.exit(0));
|
||||||
const shutdown = () => {
|
const shutdown = () => {
|
||||||
for (const stop of stops) stop();
|
for (const stop of stops) stop();
|
||||||
if (!server) process.exit(0);
|
if (busy()) console.log('stopping: finishing the running work first');
|
||||||
server.close(() => process.exit(0));
|
if (!server) return exitWhenIdle();
|
||||||
|
server.close();
|
||||||
server.closeIdleConnections();
|
server.closeIdleConnections();
|
||||||
setTimeout(() => process.exit(0), 3000).unref();
|
setTimeout(() => {
|
||||||
|
server.closeAllConnections();
|
||||||
|
exitWhenIdle();
|
||||||
|
}, 3000).unref();
|
||||||
};
|
};
|
||||||
process.on('SIGINT', shutdown);
|
process.on('SIGINT', shutdown);
|
||||||
process.on('SIGTERM', shutdown);
|
process.on('SIGTERM', shutdown);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue