Install
$ agentstack add skill-pradnyeshp-claude-skills-graceful-shutdown ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Runtime, server & signal signals
!grep -rilE "SIGTERM|SIGINT|process\\.on|signal\\.|shutdown|http\\.Server|createServer|express|fastify|nestjs|flask|fastapi|gunicorn|uvicorn|listen\\(|graceful" --include='*.*' package.json pyproject.toml go.mod Gemfile 2>/dev/null | grep -vE 'node_modules|\.git|dist|build' | head -8
Instructions
Make the service in $ARGUMENTS (or the app's entrypoint) terminate cleanly when the platform sends a shutdown signal, so an in-flight request is finished rather than severed and external resources are released. Reuse the project's server and connection objects rather than introducing a new lifecycle framework.
Method
- Handle the right signals. Trap
SIGTERM(what Kubernetes/Docker/systemd send) andSIGINT(Ctrl-C in dev). Run the shutdown routine once and guard against re-entry if a second signal arrives. - Stop accepting new work first. Close the listening socket / stop the HTTP server from taking new connections, and if the app pulls from a queue, stop consuming. Existing in-flight requests keep running; new ones are refused (or shed to another instance).
- Fail readiness immediately. Flip the readiness probe to unhealthy at the start of shutdown so the load balancer / orchestrator stops routing new traffic before the socket closes (see the
healthcheckskill). In Kubernetes, expect traffic for a moment after SIGTERM — a short pre-drain delay avoids races. - Drain in-flight work with a bounded timeout. Wait for active requests/jobs to complete, but cap the wait (e.g. 10–30s, comfortably under the platform's kill grace period). If work exceeds the deadline, log what's still pending and proceed — never block forever.
- Release resources in dependency order. After draining, close DB pools, cache/queue clients, and file handles, and flush logs/metrics/traces. Close what depends on the network before the things it depends on.
- Exit with an honest code.
exit(0)on a clean drain; a non-zero code if shutdown timed out or errored. Don't leave the process hanging — the platform willSIGKILLit and undo the graceful intent. - Verify. Test that sending SIGTERM while a slow request is in flight lets that request finish and returns before exit, that new connections are refused during drain, and that the process exits within the deadline.
Rules
- Trap SIGTERM (and SIGINT for dev), make the handler idempotent, and never let a second signal trigger a second concurrent shutdown.
- Stop new work and fail readiness before closing the socket, so the balancer drains traffic first; then drain in-flight requests.
- Always bound the drain with a timeout under the platform's kill grace period — drain, but never block shutdown indefinitely.
- Close DB/queue/cache connections and flush telemetry after draining, in dependency order, then exit with a status code that reflects success or timeout.
- End by summarizing which signals are handled, the drain timeout and how it relates to the platform grace period, the readiness behavior, and what gets closed on the way out.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Pradnyeshp
- Source: Pradnyeshp/Claude-Skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.