Proletarian is designed to shut down gracefully. WhenDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/msolli/proletarian/llms.txt
Use this file to discover all available pages before exploring further.
worker/stop! is called, it signals all worker threads to stop and waits for any in-flight jobs to finish before tearing down the thread pool. No jobs are abandoned mid-execution, and the queue is left in a consistent state.
Stopping the worker manually
Callworker/stop! when you are ready to bring down the system:
stop! blocks until the thread pool has terminated (or the termination timeout is reached — see below).
JVM shutdown hook
Setting:proletarian/install-jvm-shutdown-hook? to true tells Proletarian to register a JVM shutdown hook via java.lang.Runtime.addShutdownHook. The hook calls stop! automatically when the JVM receives SIGTERM or when the process is interrupted with Ctrl-C:
false. This is intentional: when using a component library (Component, Integrant, Mount), the library itself manages lifecycle, and you should let it call stop! rather than installing a competing shutdown hook. See the Component Integration guide for details.
Await-termination timeout
The:proletarian/await-termination-timeout-ms option controls how long stop! waits for running jobs to finish before considering the shutdown complete. The default is 10000 (10 seconds):
Running code after shutdown
Use:proletarian/on-shutdown to register a zero-argument callback that Proletarian invokes once the thread pool has fully terminated. The function’s return value is discarded:
on-shutdown is called after shutdown-executor completes, so you can safely assume that no job code is still running when the callback fires. The default is a no-op.
Handling interrupts in job handlers
Whenstop! is called, Proletarian sends a JVM thread interrupt to every worker thread. What happens next depends on what the thread is doing at that moment:
- Thread is polling — the thread sees the interrupt and stops immediately, without picking up any new job.
- Thread is running a job — the interrupt is delivered to the job’s code. Whether the job can respond to it depends on the nature of the work.
Blocking operations (automatic interrupt handling)
Operations that block the thread — such asThread/sleep, blocking I/O, JDBC calls, and core.async/<!! — respond to JVM interrupts by throwing java.lang.InterruptedException. Proletarian catches this exception and:
- Logs the
::worker/job-interruptedevent. - Leaves the job in the queue so it will be picked up and re-run when the worker restarts.
InterruptedException yourself:
Interrupted jobs are not marked as failed. They remain in the queue with their original
process-at time and will be picked up and re-executed the next time a worker starts. This is why your job handlers should be idempotent — the same job may run more than once.CPU-bound jobs (no automatic interrupt handling)
Tight loops and other CPU-intensive work do not make blocking calls, so they never receive anInterruptedException. The JVM interrupt flag is set on the thread, but the code keeps running until it checks the flag manually using Thread/isInterrupted():
Summary of shutdown behaviour
| Job state at shutdown | What happens |
|---|---|
| Polling for jobs | Stops immediately; no job is picked up |
| Running a blocking job | InterruptedException thrown; job left in queue for reprocessing |
| Running a CPU-bound job | Job finishes naturally; no new jobs are picked up afterward |
