Shards Architecture¶
Formabble uses the Shards coding language. This page is an explanation of the Shards architecture focused on how the program flow works.
The Shards Overall Architecture¶
- Shards code is written in
.shs
files which contain wires. - Wires are composed of shards connected by data flow.
- Wires are scheduled on meshes.
- When a wire is scheduled on a mesh, it goes through the following steps:
- Composing: The shards are connected and validated. This builds the wire execution graph.
- Warmup: Any initialization logic in shards runs.
- Running: The wire executes on the mesh, with data flowing shard to shard.
- Wires can be executed concurrently on a mesh in different ways using wire executors.
The Shards program lifetime¶
When a shards script is run, it undergoes the following steps:
- Script file evaluation
- Shards code is written in
.shs
files which contain the shard graph definition. These files are evaluated to create wires.
- Shards code is written in
- Wire creation
- Wires represent the shard graph and are created when evaluating the script files. A wire connects shards together into a directed acyclic graph.
- Mesh creation
- A mesh manages and runs wires concurrently on a single thread. Creating multiple meshes allows wires to run concurrently across threads.
- Wire scheduling
- Wires must be explicitly scheduled on a mesh in order to run. Scheduling a wire triggers the composing process.
- Composing of a Wire
- The process of validating connections between shards and building the full shard graph. This happens when a wire is scheduled on a mesh.
- How wires are tied together
- Wires form a directed acyclic graph via data flow between shards. The connections are validated during the composing process.
- Warmup of a Wire
- Before a wire runs, the
warmup
method is called on each shard to initialize any state it may need.
- Before a wire runs, the
- Wire running on Mesh
- The mesh
tick
method runs scheduled wires by resuming their coroutine when they are ready to continue execution.
- The mesh
The Shards Concurrency Model¶
- Wires provide task parallelism running concurrently on meshes.
- A mesh runs on a single thread, so no intra-wire parallelism.
- Shards have no shared mutable state, removing synchronization needs within a wire.
- Different meshes run independently and can run on different threads.
- Wires on the same mesh can interleave shard execution but shards have no side effects.
- Wire parameters are immutable once running.
- No shard execution ORDER guaranteed between wires on a mesh.
So in summary:
- Safety within a wire comes from shards being side effect free.
- Safety between wires comes from shard immutability and no execution order guarantees.
- Multiple meshes provide full task parallelism.
Additional Details¶
- Multiple meshes allow shard graphs to run concurrently across threads.
- A mesh provides thread isolation - wires in separate meshes run concurrently.
- Coroutines yield execution between shards in a wire and between scheduled wires.
- Shard parameters define typed, validated inputs.
- Parameters must have compatible types to connected shards.
- Validation happens once at compose time to optimize performance.
- A shard's state persists between activations.
- Shards don't share mutable state so no synchronization needed.
- Concurrent data flows minimize shared mutable state.
- Shard graph structure is invariant under deformation.
- Context variables share state between parent/child wires.
- Context variables are scoped to a wire and its children.
- Context variables avoid explicitly passing state through shards.