The Actors
Index
An overview of Anoma
A good overview of Actors can be seen by looking at the supervision tree of Anoma itself.
Kino.Process.render_app_tree(:anoma_node, direction: :left_right)
graph LR;
application_master(#PID<0.875.0>):::supervisor ---> supervisor_ancestor;
supervisor_ancestor(#PID<0.876.0>):::supervisor ---> 0;
0(Anoma.Node.Supervisor):::root ---> 1(Anoma.Node.Transport.Supervisor):::supervisor
0(Anoma.Node.Supervisor):::root ---> 6(Anoma.Node.Transaction.Supervisor):::supervisor
1(Anoma.Node.Transport.Supervisor):::supervisor ---> 2(ProxySupervisor):::supervisor
1(Anoma.Node.Transport.Supervisor):::supervisor ---> 3(Anoma.Node.Transport.TCPSupervisor):::supervisor
1(Anoma.Node.Transport.Supervisor):::supervisor ---> 4(ProxyRegister):::supervisor
4(ProxyRegister):::supervisor ---> 5(ProxyRegister.PIDPartition0):::worker
classDef root fill:#c4b5fd, stroke:#374151, stroke-width:4px;
classDef supervisor fill:#c4b5fd, stroke:#374151, stroke-width:1px;
classDef worker fill:#93c5fd, stroke:#374151, stroke-width:1px;
classDef notstarted color:#777, fill:#d9d9d9, stroke:#777, stroke-width:1px;
Mempool
A good view of visualizing Anoma can be seen through running the mempool, as it orchastrates the other actors in Anoma to act
First we will create a transaction and see how that changes the base supervision tree before executing
alias Anoma.Node.Ordering
alias Anoma.Node.Mempool
alias Anoma.Node.Router
import TestHelper.Nock
name = :anoma
node = Anoma.Node.state(name)
key = 555
zero = zero_counter(key)
pid_zero = Mempool.tx(node.mempool, {:kv, zero}).pid
#PID<0.438.0>
The previous evaluations PID can be seen in the diagram below!
{_, [pid1, pid2]} = Process.info(Process.whereis(:anoma), :links)
Kino.Process.render_sup_tree(pid2, direction: :left_right)
graph LR;
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 1(Anoma.Node.Router hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::worker
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 2(Anoma.Node.Clock plaqCqOIQ4LLCT9MAmEMV+qkqZq4+qZV2KSpqSxRZu0=):::worker
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 3(Anoma.Node.Logger BDTPKlJ5ubxM9NMrbgMzxE5jfKKn+qwnxISeroCw3xc=):::worker
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 4(Anoma.Node.Ordering rVQnNBPLju9VBsHOQzAdKaEXRK2u03vF8huvKzVPyT8=):::worker
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 5(Anoma.Node.Executor po4ivXyVtjQ9jvTtra0D2DbKIpM8YOClCmfk8JLp31k=):::worker
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 6(Anoma.Node.Mempool yg3U9BqClfT+jJkwbtuYm2WCmIgR+f6ELjodD5P4eko=):::worker
0(supervisor hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=):::root ---> 7(Anoma.Node.Pinger Oc96nqV6/0FFT/JULG5Ep+Z1c62/8f1Bi0gY9CVmJhs=):::worker
classDef root fill:#c4b5fd, stroke:#374151, stroke-width:4px;
classDef supervisor fill:#c4b5fd, stroke:#374151, stroke-width:1px;
classDef worker fill:#93c5fd, stroke:#374151, stroke-width:1px;
classDef notstarted color:#777, fill:#d9d9d9, stroke:#777, stroke-width:1px;
Now let us see what happens between the actors when we run the mempool
Kino.Process.render_seq_trace(
[Process.whereis(node.mempool.server)],
fn ->
Mempool.execute(node.mempool)
end,
message_label: &Anoma.Utility.message_label/1
)
sequenceDiagram
participant 3 AS code_server;
participant 7 AS mnesia_locker;
participant 6 AS mnesia_tm;
participant 8 AS Anoma.Node.Router hWXJ+NujE76g6g4X5Bu+KH1YtSKrur7yDUfeu0JguKY=;
participant 2 AS Anoma.Node.Logger BDTPKlJ5ubxM9NMrbgMzxE5jfKKn+qwnxISeroCw3xc=;
participant 4 AS Anoma.Node.Ordering rVQnNBPLju9VBsHOQzAdKaEXRK2u03vF8huvKzVPyT8=;
participant 1 AS Anoma.Node.Mempool yg3U9BqClfT+jJkwbtuYm2WCmIgR+f6ELjodD5P4eko=;
participant 0 AS self();
participant 5 AS #35;PID<0.438.0>;
0->>1: CALL: execute
1->>2: ADD LEVEL: info
1->>3: INFO: code_call
3->>1: INFO: code_server
1->>3: INFO: code_call
3->>1: INFO: code_server
1->>3: INFO: code_call
3->>1: INFO: code_server
1->>3: INFO: code_call
3->>1: INFO: code_server
1->>4: CALL: next_order
4->>1: INFO: tuple
1->>3: INFO: code_call
3->>1: INFO: code_server
1->>3: INFO: code_call
3->>1: INFO: code_server
1->>2: ADD LEVEL: info
1->>4: CALL: new_order
4->>1: INFO: tuple
1->>2: ADD LEVEL: info
1->>5: INFO: write_ready
1->>2: ADD LEVEL: info
1->>6: INFO: tuple
6->>1: INFO: mnesia_tm
1->>7: INFO: tuple
7->>1: INFO: mnesia_locker
1->>7: INFO: release_tid
1->>6: INFO: delete_transaction
1->>2: ADD LEVEL: info
1->>2: ADD LEVEL: info
1->>8: CAST: cast
1->>0: INFO: tuple
{:ok, 1}
As we can see, we get a fairly solid overview of what actors sent what messages
We can also see what processes startup when we start an execution
Kino.Process.render_seq_trace(
[Process.whereis(node.mempool.server)],
fn -> Mempool.tx(node.mempool, {:kv, increment_counter_val(555)}).pid() end,
message_label: &Anoma.Utility.message_label/1
)
#PID<0.1147.0>
Kino.Process.render_seq_trace(
:all,
fn -> Anoma.Node.Logger.add(node.logger, :info, "help") end,
message_label: &Anoma.Utility.message_label/1
)
:ok