RPC System
Capability-based RPC with promise pipelining
RPC System
ZAP C++ includes a capability-based RPC system with promise pipelining, allowing efficient distributed communication.
Core Concepts
Capabilities
A capability is a reference to a remote object. If you have a capability, you can call methods on it. This is the object-capability security model:
- No ambient authority - You can only access what you're given
- Unforgeable references - Capabilities cannot be guessed or fabricated
- Delegation - You can pass capabilities to others
- Revocation - Dropping a capability removes access
Promise Pipelining
When a method returns a capability, you can immediately call methods on that capability without waiting for the first call to complete. The system automatically pipelines requests:
This dramatically reduces latency in distributed systems.
Defining Interfaces
Implementing Servers
Each interface method becomes a virtual function to override:
Running a Server
Using EzRpcServer
The simplest way to start a server:
Manual Setup
For more control:
Creating Clients
Using EzRpcClient
Promise Pipelining in Action
Error Handling
Returning Errors
On the server side:
Cancellation
Dropping a promise cancels the request:
Streaming
Schema
Server Implementation
Two-Party Protocol
For direct connections without a central server:
Bidirectional Communication
Both sides can export capabilities:
The client passes a ChatClient capability to the server, which can then call back to the client.
Connection Management
Detecting Disconnection
Graceful Shutdown
Best Practices
- Use promise pipelining - Avoid unnecessary round trips by chaining calls
- Return capabilities - Instead of IDs, return object references
- Cancel unused promises - Free server resources early
- Handle errors - Always catch exceptions from RPC calls
- Use streaming for large data - Don't send huge messages at once
- Keep interfaces focused - Small interfaces are easier to mock and test
- Document capability lifecycles - Make it clear who owns what
Performance Considerations
- Batch requests - Multiple pipelined calls are more efficient
- Reuse capabilities - Don't re-bootstrap for each operation
- Consider locality - Pass capabilities to where the data is
- Monitor message sizes - Large messages can cause latency spikes
Next Steps
- Learn about the KJ Async Library
- See RPC Examples
- Explore the API Reference