call when you need the answer before going on, such as reading a price or checking a balance. The other actor’s handler runs now, inside your call, and you get its return value. Use send to tell another actor something happened: a message reaches it a little later, and you get nothing back. Use runtime.emit_event to let apps and people follow what the actor does: an entry goes into your actor’s event log, with no other actor involved.
This page builds three actors: a price list, a ledger, and a shop that asks one for a price and tells the other about each sale.
First, install the CLI. The last step deploys, so it needs a funded wallet.
1. Create the project
A project can hold several actors. Create a project for the shop, then add the other two:Output
2. Write the shop
Replaceactors/shop/main.py with:
Calls
call(address, handler, args, cycles_limit=...) runs another actor’s handler and returns what it returns. args arrives at the other handler as its payload, and cycles_limit caps its work. The other actor sees yours as self.sender, and it can’t call back into your actor during the call.
If it raises, call raises ActorCallError, and your whole call is undone unless you catch it.
Messages
send(address, payload) sends a message and returns at once. It reaches the other actor’s handle_message handler a little later, as its own call, with your actor as self.sender. If the other actor fails, your call still goes through. A handler that sends must be @deferred, as order is.
A sent message is delivered once, and only if your call goes through. Your actor pays for delivery, and if it can’t pay when the message is due, the message is dropped.
Events
runtime.emit_event(name, value) adds an entry to the actor’s event log, which anyone can read with cowboy actor logs <actor>.
3. Write the ledger
The ledger takes sales only from the shop it trusts. Replaceactors/ledger/main.py with:
Who may call you
A decorator can’t hold an address you learn later, such as the shop’s here. Instead, make the handler@public and check self.sender against the stored address first thing, as handle_message does. A check that raises undoes the call. Keep an actor safe covers the rest.
4. Write the price list
The price list answersprice for anyone, and only its owner sets prices. Replace actors/prices/main.py with:
5. Test them
The tests don’t need the other actors running:CallMock stands in for the price list, and mock_host.get_send_log() lists the messages the shop sent. Replace tests/test_shop.py with:
Output
6. Connect them
Deploy all three, set a price, then tell the shop and the ledger about each other. Eachdeploy prints the actor’s address:
Output
Output
7. Place an order
Output
Output
Output
logs shows order.placed with the item and its price. The message reaches the ledger a little after the call, so give it a moment: state then shows total at 3.