# Architecture

Flowmetal is an interpreted language backed by a durable event store.
The execution history of a program persists to the durable store as execution precedes.
If an interpretation step fails to persist, it can't have external effects.
This is the fundamental insight behind Microsoft AMBROSIA.
The event store also provides Flowmetal's only interface for communicating with external systems.
Other systems can attach to Flowmetal's data store and send events to and receive them from Flowmetal.
For instance Flowmetal contains a reference implementation of a HTTP callback connector and of a HTTP request connector.
This allows Flowmetal programs to request that HTTP requests be sent on their behalf, consume the result, and wait for callbacks.

A Flowmetal deplyoment looks like this -

```
                  +----------------------------+
                +---------------------------+  |
              +--------------------------+  |--+
              | External HTTP service(s) |--+
              +--------------------------+
                 ^                  ^
                 |                  |
                 v                  v
 +-----------------------+   +------------------------+
 | HTTP server connector |   | HTTP request connector |
 +-----------------------+   +------------------------+
                 ^                  ^
                 |                  |
                 v                  v
                +--------------------+    +----------------------+
                | Shared event store |    | Shared program store |
                +--------------------+    +----------------------+
                           ^                        ^
                           |                        |
                           v                        v
                          +--------------------------+
                          | Flowmetal interpreter(s) |
                          +--------------------------+
```

Users interact with Flowmetal by creating (or editing) **Programs**.

An instance of a Program is called a **Task**.
Every Task has a unique **Inbox** and **Outbox**.
Comparable systems call the unit of execution a Process; we prefer Task because Process invites conflation with a Unix process or thread and our Tasks are entirely portable.

Tasks interact with the outside world by producing **Requests** into their Outbox.
For example an instance of a Task could request that some other Task be executed.
Delivering messages to some other Task, or making API calls against external services would be other good examples of Requests.

Tasks receive the results of their Requests and other external events as **Messages** in their **Inbox**.
A request that some other Task be executed would be responded to with a Message identifying the other task.
The requesting Task could choose to wait on the requested Task, or could disregard it.
Likewise the results of external requests return as Messages.
