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