Skip to main content

Module lifecycle

Use each lifecycle phase for a distinct level of resource ownership.

PhasePurposeOrder
initializeAcquire resources and prepare local stateDependency-first order
setupConnect the module to other service componentsDependency-first order
runPerform finite or long-running workInvoked in dependency-first order; runs may overlap
stopAsk running work to finishDispatched in reverse order; waits retain existing concurrency
teardownUndo setupSequential reverse order
shutdownRelease initialized resourcesSequential reverse order
cleanupPerform unconditional final cleanupSequential reverse order

For modules without dependency edges, stable instance IDs provide the tie-breaker, so installation order does not change the lifecycle trace. Calling run() seals the composition before any lifecycle callback starts. Dependencies are available in setup and run; references are available only in run and do not affect ordering.

Partial startup

Microde tracks how far each module progressed. If initialization fails, only modules that reached initialization are shut down, but every installed module is cleaned up. If setup fails, only modules that reached setup are torn down.

This lets lifecycle methods assume that their corresponding forward phase was reached. Cleanup is the exception: it must be safe after any earlier outcome.

Implementation guidance

  • Keep lifecycle methods idempotent where practical.
  • Let errors propagate; Microde records them and continues the appropriate unwind phases.
  • Do not call panic() for recoverable lifecycle failures because it exits the process without unwinding.
  • Ensure an active module's stop() eventually settles its run() promise.