blob: 27c940101d1239808dd9eb23fa3b4a5c6b430bd6 [file] [log] [blame] [view]
## Agents
An `Agent` is a singleton-per-session component which runs outside of
the scope of a Story without any graphical UI.
Agents can schedule tasks (i.e. they can register to be woken up by the
framework to perform work), and provide services to other modular components.
Any modular component can connect to an agent and access its services (including
modules, shells, and other agents).
### Environment
An agent is given access to two services provided by the modular framework in
its incoming namespace:
* `fuchsia.modular.ComponentContext` which gives the agent access to
functionality which is shared across components run under the modular
framework (e.g. modules, shells, agents).
* `fuchsia.modular.AgentContext` which gives agents access to agent specific
functionality, like creating entity references and scheduling tasks.
An agent is expected to provide two services to the modular framework in its
outgoing namespace:
* `fuchsia.modular.Agent` which allows the framework to forward connection
requests from other components and tell the agent to run tasks.
* `fuchsia.modular.Lifecycle` which allows the framework to signal the agent
to terminate gracefully.
The aforementioned services enable communication between agents and the modular
framework, but agents can also expose custom FIDL services to components. For a
more detailed explanation of the mechanism which enables this service exchange
see Communication Mechanisms below.
### Lifecycle
For most agents, when a component connects to an agent the framework will give
the component an `AgentController`. When the connecting component drops the
`AgentController` connection, and there are no outstanding connections, the
agent will be killed by the framework.
There are some agents for which the `sessionmgr` maintains an `AgentController`,
and thus the agent remains alive for the duration of the session. These
"session" agents also get access to `fuchsia.modular.PuppetMaster` in their
incoming namespace.
### Communication mechanisms
Components can communicate with agents in two different ways: either by
connecting to a FIDL service exposed by the agent, or over a `MessageQueue`.
Which communication method is appropriate depends on the semantics of the
messages being passed. FIDL requires both agent and client to be running,
whereas message queues allow the life cycles of the sender and receiver to be
different.
#### FIDL Services
The modular framework will forward a `fuchsia.sys.ServiceProvider` request via
`fuchsia::modular::Agent.Connect` call, and will also provide the agent with an
identifier for the client which is requesting the service provider.
Any services added to the service provider will be exposed directly to the
connecting component.
To illustrate this, consider a module connecting to an agent:
The module calls `ConnectToAgent` on its `ComponentContext`, which contains a
`ServiceProvider` request as well as an `AgentController` request.
The agent controller request is used by the framework to keep the agent alive
until the agent controller is closed by the client. If more than one client is
connected to the same agent, the agent will be kept alive until all agent
controllers have been closed.
The service provider request is forwarded to the agent, along with a string
which identifies the client connecting to the agent.
#### Message Queues
Messages sent over message queues are untyped, but allow the life cycles of the
reader and writer to be decoupled. For example, an agent may provide a module
with a message queue which it can use to send messages to the agent. The agent
can then register to be woken up when a message is delivered on the queue.