<<../_v2_banner.md>>
Component instances progress through four major lifecycle events: create, start, stop, destroy and purge.
Component instances may retain isolated persistent state on a storage medium while they are not running, which can be used to help them maintain continuity across restarts.
A component instance may be created in the following ways:
Every component instance has a moniker that uniquely identifies it, determined by its path from the root.
Once created, a component instance can then be bound to, started, or destroyed.
A component instance A
binds to another component instance B
when A
connects to some capability that is provided by B
. When this happens, component instance B
is started, unless it was already started. In most cases, this is the most common reason for a component instance to start.
Concretely, there are two ways that A
can bind to B
:
A
connects to a capability in its namespace which is exposed or offered by B
. This is the most common way.A
binds to the fuchsia.component.Binder
framework protocol which is exposed or offered by B
. Unlike a traditional capability, this protocol is implemented by the component framework.The word “bind” is meant to imply that a component is run on account of being “bound” by its clients. In theory, when no more clients are bound to a component, the framework could stop running it, but this behavior isn't currently implemented.
Note: For more details on running components during development, see Run components.
Starting a component instance loads and runs the component's program and provides it access to the capabilities that it requires.
The most common reason for starting a component instance is when another component requests to use one of its instance's exposed capabilities. However, there are other ways to start a component, such as the [ffx component start
][ref-ffx-start] command.
Once started, a component instance continues to run until it is stopped.
Stopping a component instance terminates the component's program but preserves its persistent state so that it can continue where it left off when subsequently restarted.
The component framework may stop a component instance for the following reasons:
A component can implement a lifecycle handler (example) to be notified of its impending termination and other events on a best effort basis. Note that a component can be terminated involuntarily and without notice in circumstances such as resource exhaustion, crashes, or power failure.
Components can stop themselves by exiting. The means by which a component exits depend on the runner that runs the component.
Once stopped, a component instance can then be restarted or destroyed.
Once destroyed, a component instance ceases to exist and cannot be restarted. New instances of the same component can still be created but they will each have their own identity and state distinct from all prior instances. From an external point of view, the component doesn't exist anymore in the component topology.
Purging a destroyed component instance deletes any persistent storage it's using and all its internal state from component_manager.
Component manifests let you mark a child as eager
, which causes the component framework to implicitly bind to that child when any component binds to the parent. In other words, this causes the child to be immediately started whenever the parent is started.
If the eager child fails to start for any reason (such as a missing component), component manager exhibits the following behavior:
[component_manager] ERROR: Failed to route protocol `fuchsia.appmgr.Startup` with target component `/startup`: failed to resolve "fuchsia-pkg://fuchsia.com/your_component#meta/your_component.cm": package not found: remote resolver responded with PackageNotFound
An eager
component should be in the same package set as its parent since the component will be started at the same time as its parent. Typically eager
components should be in the product's base package set.
Components marked as eager
whose ancestors are marked eager
up to the root will cause system crashes when they are not present. This is important because many tests and products create system images containing only a subset of all available components. You should declare these components using core realm shards to ensure they can be safely excluded from test builds and product images containing subsets of components.
You can determine if your package is in base. If your package is not present in base the command below will print no output.
fx list-packages --base {{ '<var label="package name">my-package</var>' }}
You can also look at all the packages in the the base package set.
fx list-packages --base