Created -> Running -> StoppedMicroservice Startup, Cancellation and Graceful Shutdown
The complete path from generated configuration to safe graph shutdown.
When to use
Use this page when implementing maker hooks, owning resources, or diagnosing startup and shutdown.
Behavior
- Construction and activation are separate: makers create objects, graph binding connects them, and
startopens runtime resources. - Managed connectors have two lifecycle boundaries: core client resources and inbound Worker admission.
- Downstream resources and Sinks start before managed Worker admission, ordinary Sources, and network listeners because inbound resources may emit immediately.
- Shutdown closes network admission first so already accepted handlers can finish while endpoint consumers, graph pools, Sinks, and clients remain alive.
- Ordinary Sources drain before managed Worker admission stops; this preserves accepted flows such as Cron to Temporal.
- Shutdown then drains graph-work producers and only afterward observes the nested ParallelCall registry.
- Task pools, priority pools, delay timers, and storage stop before ParallelCall drain because an accepted pool task can create a late parallel child.
- DataSinks stop after graph drain, managed connector clients stop after Sinks, and graph ownership is released only when callbacks can no longer run.
- Telemetry remains available through cleanup so shutdown failures and timeout events remain visible.
Startup phases
Endpoint consumers and routes are bound before admission opens. Languages without managed connectors simply skip the connector-specific phases.
Running phase
Makers do not run per message. Endpoint consumers repeatedly invoke the long-lived function instances created at startup.
- A function maker normally runs once per generated function or endpoint instance.
- Per-request state belongs in request hooks, not unsynchronized shared maker state.
- A DataSource owns inbound transport or polling; a DataSink owns outbound submission.
- A managed connector can own both inbound Workers and outbound clients, so admission and core shutdown are separate.
Graceful shutdown phases
Work accepted before the stop signal retains endpoint state, graph resources, Sinks, and clients until its safe completion boundary. Exact server ownership differs by language, but the dependency invariant remains the same.
shutdownTimeout.Why pools stop before ParallelCall drain
A task already accepted by a TaskPool, PriorityTaskPool, or DelayPool may create a ParallelCall near the end of its execution. Reading an empty parallel registry before that producer finishes creates a race: shutdown can continue and the child appears afterward. ServiceLib therefore quiesces all graph-work producers first, then drains registry snapshots until no nested work remains.
- Pool
stopmeans close admission and drain accepted tasks within the shared deadline. - Storage remains part of the same producer-resource phase and is stopped before the final parallel observation.
- Sinks remain available through both phases so accepted work can still publish results.
Hooks and boundaries properties
Generated extension points and runtime-owned lifecycle boundaries.
shutdownTimeoutmillisecondsTotal graceful-shutdown window shared by all phases.
workerStopTimeoutmillisecondsTemporal connector Worker drain cap; zero inherits the service timeout and a positive value cannot exceed it.
Source admissionboundaryStops before producer pools, nested graph drain, and Sinks.
Managed admissionboundaryStops Worker polling after ordinary Sources drain and before producer pools.
Endpoint consumerbound objectLives from graph binding until transports and connector callbacks can no longer invoke it.
Pool and timer drainproducer boundaryCompletes before the ParallelCall registry is observed.
Telemetryfinal boundaryStops after runtime resources.
Lifecycle outline
configure -> make once -> bind -> start -> admit -> drain -> stop