ARCHIVED from builddistributedsystem.com on 2026-04-28 — URL: https://builddistributedsystem.com/tracks/messenger/tasks/task-1-2-3-async-rpc
TASK

Implementation

Synchronous RPC blocks the caller until a reply arrives, which prevents the node from handling other messages during that time. In high-throughput distributed systems, asynchronous RPC is preferred.

Your task is to implement an async_rpc method that:

  1. Sends a message to a target node
  2. Registers a callback function keyed by the outgoing msg_id
  3. Returns immediately (non-blocking)
  4. When a reply arrives (with matching in_reply_to), invokes the callback with the reply body

Implement a batch_echo message type: the node receives a list of strings, sends an echo RPC for each one to itself (loopback), and collects all replies using callbacks. Once all replies are collected, respond with the results.

Request:  {"type": "batch_echo", "msg_id": 1, "values": ["a", "b", "c"]}
Response: {"type": "batch_echo_ok", "in_reply_to": 1, "results": ["a", "b", "c"]}

For testing, the node should echo to itself (src and dest are the same node).

Sample Test Cases

Init and echo still workTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"echo","msg_id":2,"echo":"async"}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
{"src": "n1", "dest": "c1", "body": {"type": "echo_ok", "echo": "async", "in_reply_to": 2, "msg_id": 1}}
Callback registration sends RPCTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"batch_echo","msg_id":2,"values":["x"]}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
{"src": "n1", "dest": "n1", "body": {"type": "echo", "echo": "x", "msg_id": 1}}

Hints

Hint 1
Store callbacks in a dictionary keyed by msg_id
Hint 2
When a reply arrives, look up the callback by in_reply_to and invoke it
Hint 3
The callback should receive the reply body as its argument
Hint 4
Use a handler map to dispatch different message types
Hint 5
Async RPC allows the node to continue processing other messages while waiting
OVERVIEW

Theoretical Hub

Concept overview coming soon

Key Concepts

asynchronous programmingcallbacksnon-blocking I/Oevent-driven
main.py
python
Implement Async RPC Using Callbacks - The Messenger | Build Distributed Systems