You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+27-10Lines changed: 27 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,9 +26,7 @@ If you want to make your own app try copying this to get started: [Example Canop
26
26
27
27
## Why Canopy?
28
28
29
-
Distributed C++ systems have always been hard. Getting two components talking across a process boundary, a network connection, or a security enclave typically means writing a large amount of hand-rolled serialization, connection management, and error-handling code — code that is fragile, hard to test, and has to be rewritten every time the transport or wire format changes.
30
-
31
-
Canopy takes the classical RPC model — define an interface, get a proxy on the caller side and a stub on the callee side — and brings it fully up to date with modern C++:
29
+
Distributed C++ systems have always been hard. Getting two components talking across a process boundary, a network connection, or a security enclave, typically means writing a large amount of hand-rolled serialization, connection management, and error-handling code — code that is fragile, hard to test, and has to be rewritten every time the transport or wire format changes. Canopy is trying to help with that as an absolute expression of abstraction using machine generated interfaces, with the hope of removing 70-80% of coding effort.
32
30
33
31
<divalign="center">
34
32
<pre>
@@ -101,7 +99,7 @@ blocking co_await
101
99
</pre>
102
100
</div>
103
101
104
-
**Distributed by design.** Each machine or process hosts its own root zone. Child zones branch from it for plugins, enclaves, or any other isolation boundary. Multiple nodes connect as peers over the network. Objects living at any depth in any node's zone tree can call objects at any depth in any other node's tree — the routing is automatic.
102
+
**Distributed by design.** Each machine or process hosts its own root zone. Child zones branch from it for plugins, enclaves, or any other isolation boundary. Multiple nodes connect as peers over the network. Objects living at any depth in any node's zone tree can call objects at any depth in any other node's tree — the routing is automatic. With TUN implementation planned it is hoped that each RPC object has the option of having its own exposed IP address.
105
103
106
104
---
107
105
@@ -115,7 +113,28 @@ blocking co_await
115
113
</pre>
116
114
</div>
117
115
118
-
**Serialization formats is a choice, not a commitment.** Binary YAS format for production throughput, compressed binary for bandwidth-constrained links, JSON for human-readable debugging and cross-language interop, Protocol Buffers for teams that need a language-neutral wire format. The format can be negotiated per-connection or overridden per-call.
116
+
**No Serialization format lockin.** Canopy can be extended to use any reasonable serialisation format. Binary YAS format for C++ high performance throughput, compressed binary for bandwidth-constrained links, JSON for human-readable debugging and cross-language interop, Protocol Buffers for teams that need a language-neutral wire format. The format can be negotiated per-connection or overridden per-call.
117
+
118
+
---
119
+
120
+
<divalign="center">
121
+
<pre>
122
+
[ Machine A ] [ Machine B ] [ Machine C ]
123
+
| | |
124
+
Owns Object <---shared_ptr--- Receives Ref |
125
+
| | |
126
+
| ---shared_ptr--------> Receives Ref
127
+
| (B can drop Ref) |
128
+
| |
129
+
Object Kept Alive <-------------------------- Active Ref
130
+
131
+
</pre>
132
+
</div>
133
+
134
+
**Canopy extends C++ RAII across the network**. Using rpc::shared_ptr and rpc::optimistic_ptr, you can manage the lifetime of remote objects as easily as local ones, even in complex multi-hop topologies.
135
+
136
+
-**rpc::shared_ptr<T>**: Mimics std::shared_ptr behavior across the wire. It maintains a distributed reference count. If Machine A shares an object with Machine B, and Machine B passes that reference to Machine C, the object on Machine A remains alive until both B and C have released their pointers.
137
+
-**rpc::optimistic_ptr<T>**: Optimized for performance where the developer assumes the object will remain valid for the duration of the call, good for long lived objects such as llms and databases, or to break circular dependencies.
119
138
120
139
---
121
140
@@ -156,21 +175,19 @@ blocking co_await
156
175
157
176
**Remote reflection.** Canopy carries interface metadata across zone boundaries, making it possible to discover what interfaces a remote object supports at runtime. This opens the door to generic tooling, dynamic proxies, and runtime composition — capabilities that are normally reserved for languages with built-in reflection and are unusual in a C++ RPC system. One practical application is implementing Model Context Protocol (MCP) services: because Canopy can enumerate the methods and types of a remote object at runtime, it can generate MCP tool descriptions dynamically, allowing AI assistants to discover and call C++ services without any hand-written schema.
158
177
159
-
If you are building a C++ system that needs components to talk to each other — whether on the same machine, across a data centre, or inside a hardware security boundary — Canopy is designed to make that straightforward rather than painful.
160
-
161
178
---
162
179
163
180
## Key Features
164
181
165
182
-**Type-Safe**: Full C++ type system integration with compile-time verification
0 commit comments