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).
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.
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.
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.
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.
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.