Lifecycle Callbacks and Restart Control
🚧 Documentation is under development
The Holoscan SDK guide is currently under active development. Some sections may be incomplete or change without notice.
Questions? Contact RidgeRun or email to support@ridgerun.com.
-
Overview
-
Build, Run, and Validate
-
Core Concepts
-
Operators and Graphs
-
Tensor Data and Memory
-
Interprocess Communication
-
-
Application and Operator Development
- Building an HSDK Application
- Writing a Minimal Operator
- Typed Parameters and Configuration
- Reading, Writing, and Forwarding Data
- Writing Tensor Operators
- Complete Operator Patterns
- Authoring Runtime Behavior
- Runtime Parameter Updates
- Lifecycle Callbacks and Restart Control
- Performance and Debugging
- SDK Source Map
-
Operator Reference
-
Core Operators
-
Holoscan Camera
-
Holoscan RidgeRun
- Overview
- Build and Installation
- ArgusCameraOp
- V4L2SourceOp
- V4L2UserPtrSourceOp
- BgraToPlanarTensorOp
- RawBayerToBgraOp
- RawBayerToYoloTensorOp
- YuyvToBgraOp
- TensorRtInferenceOp
- DrmDisplayOp
- DrmBgraDisplayOp
- X11DisplayOp
- CudaCompositorOp
- DepthColorizerOp
- FakesinkOp
- FrameSkipperOp
- InterprocessSrcOp
- TestPatternOp
-
-
Migration from Holoscan 4.x
-
Examples
-
Core
-
Holoscan Camera
-
Holoscan RidgeRun
-
-
Benchmark and Use Cases
-
Holoscan vs GStreamer
- Overview
-
Capture and Display
-
Capture and Inference
- Compare the workloads
- Implemented Applications
- Framework Selection
- Interprocess
-
Lifecycle Callbacks and Restart Control
An operator may need setup work before it can process data: opening a device, allocating storage, warming up processing, or arming a producer. Lifecycle callbacks organize that preparation and release it when the operator stops. They complement runtime parameter updates when a change requires preparation to run again.
Use simple start/stop overrides when they cover the operator's needs. Staged callbacks add earlier preparation phases and resource dependencies. When the compiled plan permits restart, a bounded transaction repeats the required lifecycle work within that plan; a topology change requires a new graph and plan.
Use lifecycle only when preparation must change
Choose the path from the work that needs to change:
| Application need | Use this path |
|---|---|
| Process each selected value | The operator's compute() callback
|
| Open, allocate, warm up, arm, stop, or release resources | Lifecycle callbacks on this page |
| Repeat preparation for an admitted running operator | A bounded restart transaction on this page |
| Add ports, change topology, or exceed admitted capacity | Stop the session and compile a replacement graph |
The Lifecycle in the NVIDIA Holoscan SDK documentation introduces the callback sequence. The rest of this page connects that sequence to dependencies, restart authority, and parameter changes.
Register the Stages the Operator Needs
The forward LifecycleStage sequence is Configure, Discover, Allocate, WarmUp, Arm and Start, followed by the Stop and Release teardown checkpoints. The compiler schedules stage barriers and dependencies; an unregistered stage can be a logical skipped checkpoint instead of a callback.
spec.lifecycle() registers methods returning LifecycleStatus and taking LifecycleContext&. The callback binding requires the appropriate concrete method signature, including noexcept. A required stage must have its callback; an optional stage permits absence. Optional does not mean its registered callback is ignored.
The lifecycle-callbacks example registers preparation and teardown in the producer's setup method:
spec.lifecycle()
.stage(holoscan::LifecycleStage::kAllocate, &FrameProducer::allocate)
.optional(holoscan::LifecycleStage::kStart, &FrameProducer::on_start)
.optional(holoscan::LifecycleStage::kStop, &FrameProducer::on_stop)
.optional(holoscan::LifecycleStage::kRelease, &FrameProducer::release)
.produces(holoscan::LifecycleStage::kAllocate, kFrameTableReady);
This is a setup fragment, not a complete operator. The example defines the methods, dependency key and graph around it. Do not register an advanced Start or Stop callback on an operator that also overrides the legacy method for that same stage.
LifecycleStatus distinguishes Ok, Skipped, RetryableFailure and FatalFailure. Report the actual status; naming a failure retryable does not give the application an unrestricted retry loop. LifecycleContext identifies the current phase and provides the exact parameter generation for that callback. Startup, restart preparation, rollback, restoration and shutdown can use different phase-selected views; do not retain a parameter reference between them.
Declare Dependencies During Composition
A producer can declare a stage fact with produces(), and a consumer can declare requires_dependency() for the same fact. In the example, the consumer's Allocate waits for the producer's frame-table fact. graph.lifecycle().before() expresses a direct same-stage ordering rule; the demo separately orders producer Start before consumer Start.
These declarations are compiler inputs. Calling another operator's lifecycle method manually bypasses the schedule and its evidence. Keep sample processing in compute and resource preparation in the appropriate registered checkpoint.
Opt into Bounded Restart Transactions
Initial startup does not imply permission to restart an active operator. Set CompileOptions::lifecycle_transactions with positive capacities that meet the compiler-derived requirements, and declare the permitted targets and origins before compilation. Absence disables dedicated active restarts and lifecycle-mutable parameter transactions. Standard, Robotics and Research profiles can admit this mechanism. Every operator's effective profile must support it: a RealTime or Regulated region rejects the opt-in even when the outer graph uses a more permissive profile.
The restart-control demo grants self and external restart of its worker through allow_self_restart() and allow_external_restart(). Unlisted targets remain unauthorized. Other cross-target origins need their own declared authority; a run-bound reference alone does not grant it.
Resolve the accepted plan's target through RunSession::operator_ref(), obtain an authorized lifecycle_control() handle, and call request_restart() from outside runtime callbacks. The default first forward stage is Configure. An accepted receipt means the request was queued and an activation fence installed, not that the restart succeeded.
An already running compute callback finishes before restart work begins; an idle target restarts at the control safe point before its next compute. The admitted dependency closure determines the affected operators and preparation work within the plan's resource ceilings. A target stage cannot be used to bypass required dependencies.
Check the Receipt After the Request
Inspect the receipt or await() it from application control code. Check the terminal disposition, including failures and rollback, instead of equating acceptance or terminalization with success. A timeout is only an observation limit and does not cancel the transaction.
Inside compute, ExecutionContext::request_restart() provides nonblocking, allocation-free submission for admitted self or cross-target requests. The callback must return before the fence can take effect; it cannot wait for its own restart. Lifecycle callbacks and dispatcher code must not invoke the external control handle's restart or await operations.
Update a Lifecycle-Mutable Field
lifecycle_mutable(stage) declares the earliest forward stage invalidated by a field change. An admitted parameter patch then uses a lifecycle transaction to prepare the candidate while the affected work is quiesced. It is different from a runtime-mutable scalar becoming available at the next compute boundary.
The schema marker, parameter-update admission, transaction capacities and caller policy all remain necessary. The change must fit the accepted topology, resource recipes and capacity bounds. A new port, enlarged unadmitted tensor bound or replacement graph still requires recompilation. See Runtime Parameter Updates for candidate and publication states.