Looks very cool, especially passing functions back and forth. But then I wonder, what would I actually use that for? You mention that it’s schemaless as if that’s a good thing. Having a well defined schema is one of the things I like about tRPC and zod. Is there some way that you get the benefits of a schema with less work?
Cap'n Web: a new RPC system for browsers and web servers
51–60 of 305 posts
Re: Cap'n Web: a new RPC system for browsers and web servers
#52> RPC is often accused of committing many of the fallacies of distributed computing. > But this reputation is outdated. When RPC was first invented some 40 years ago, async programming barely existed. We did not have Promises, much less async and await. I'm confused. How is this a "protocol" if its core premises rely on very specific implementation of concurrency in a very specific language?
There's been a renaissance in the tools, but now we mainly use them like "REST" endpoints with the type signatures of functions. Programming language features like Future and Optional make it easier to clearly delineate properties like "this might take a while" or "this might fail" whereas earlier in RPC, these properties were kind of hidden.
Re: Cap'n Web: a new RPC system for browsers and web servers
#53Earlier quoted context omitted.
The state only lives for a single RPC session. When using WebSockets, that's the lifetime of the WebSocket. But when using the HTTP batch transport, a session is a single HTTP request, that performs a batch of calls all at once. So there's actually no need to hold state across multiple HTTP requests or connections, at least as far as Cap'n Web is concerned. This does imply that you shouldn't design a protocol where i…
^ maybe the most knowledgable person in the world about these gritty details RPC SDKs should have session management, otherwise you end up in this situation: "Any sufficiently complicated gRPC or Cap'n'Proto program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Akka"
Re: Cap'n Web: a new RPC system for browsers and web servers
#54I really dig the flexibility of transport. Having something that works over postMessage is totally clutch!! > Similarly, supports passing objects by reference: If a class extends the special marker type RpcTarget, then instances of that class are passed by reference, with method calls calling back to the location where the object was created. Can this be relaxed? Having to design the object model ahead of time for Rp…
With that said, I do think we ought to support `new RpcStub(myObject)` to explicitly create a stub around an arbitrary class, even if it doesn't extend `RpcTarget`. It would be up to the person writing the `new RpcStub` invocation to verify it's safe.
Re: Cap'n Web: a new RPC system for browsers and web servers
#55This seems like a similar and more feature complete / polished version of JSON RPC? The part that's most exciting to me is actually the bidirectional calling. Having set this up before via JSON RPC / custom protocol the experience was super "messy" and I'm looking forward to a framework making it all better. Can't wait to try it out!
Yeah, JSON RPC doesn't support the pass-by-reference and lifecycle management stuff. You just have a static list of top-level functions you can call. This makes a pretty big difference in what kinds of APIs you can express. OTOH, JSON RPC is extremely simple. Cap'n Web is a relatively complicated and subtle underlying protocol.
Actually the author of JSON RPC suggested that method names could be dynamic, there's nothing in the spec preventing that.
https://groups.google.com/g/json-rpc/c/vOFAhPs_Caw/m/QYdeSp0...
So you could definitely build a cursed object/reference system by packing stuff into method names if you wanted. I doubt any implementations would allow this.
But yes, JSON RPC is very minimal and doesn't really offer much.
Re: Cap'n Web: a new RPC system for browsers and web servers
#56Looking at this quickly, it does seem to require (or strongly encourage?) a stateful server to hold on to the import and export tables and the state of objects in each. One thing about a traditional RPC system where every call is top-level and you pass keys and such on every call is that multiple calls in a sequence can usually land on different servers and work fine. Is there a way to serialize and store the import/…
The state only lives for a single RPC session. When using WebSockets, that's the lifetime of the WebSocket. But when using the HTTP batch transport, a session is a single HTTP request, that performs a batch of calls all at once. So there's actually no need to hold state across multiple HTTP requests or connections, at least as far as Cap'n Web is concerned. This does imply that you shouldn't design a protocol where i…
Re: Cap'n Web: a new RPC system for browsers and web servers
#57> .map() is special. It does not send JavaScript code to the server, but it does send something like "code", restricted to a domain-specific, non-Turing-complete language. The "code" is a list of instructions that the server should carry out for each member of the array.
> But the application code just specified a JavaScript method. How on Earth could we convert this into the narrow DSL? The answer is record-replay: On the client side, we execute the callback once, passing in a special placeholder value. The parameter behaves like an RPC promise. However, the callback is required to be synchronous, so it cannot actually await this promise. The only thing it can do is use promise pipelining to make pipelined calls. These calls are intercepted by the implementation and recorded as instructions, which can then be sent to the server, where they can be replayed as needed.
Re: Cap'n Web: a new RPC system for browsers and web servers
#58Earlier quoted context omitted.
The state only lives for a single RPC session. When using WebSockets, that's the lifetime of the WebSocket. But when using the HTTP batch transport, a session is a single HTTP request, that performs a batch of calls all at once. So there's actually no need to hold state across multiple HTTP requests or connections, at least as far as Cap'n Web is concerned. This does imply that you shouldn't design a protocol where i…
Hmm so websocket reconnects could break state? Important to know when building on this, to e.g. re-establish the object graph when beginning a reconnected session? Or when using the http protocol is a possibility - to e.g. always include the "get object" as the first call in the batch.
FWIW the way I've handled this in a React app is, the root stub gets passed in as a prop to the root component, and children call the appropriate methods to get whatever objects they need from it. When the connection is lost, a new one is created, and the new root stub passed into the root component, which causes everything downstream to re-run exactly as you'd want. Seems to work well.
Re: Cap'n Web: a new RPC system for browsers and web servers
#59Looking at this quickly, it does seem to require (or strongly encourage?) a stateful server to hold on to the import and export tables and the state of objects in each. One thing about a traditional RPC system where every call is top-level and you pass keys and such on every call is that multiple calls in a sequence can usually land on different servers and work fine. Is there a way to serialize and store the import/…
That's what I noticed reading through this. It looks like the server affinity is accomplished by using websockets. The http batching simply sends all the requests at once and then waits for the response. I don't love this because it makes load balancing hard. If a bunch of chatty clients get a socket to the same server, now that server is burdened and potentially overloadable. Further, it makes scaling in/out servers…
Re: Cap'n Web: a new RPC system for browsers and web servers
#60The section on how they solved arrays is fascinating and terrifying at the same time https://blog.cloudflare.com/capnweb-javascript-rpc-library/#... . > .map() is special. It does not send JavaScript code to the server, but it does send something like "code", restricted to a domain-specific, non-Turing-complete language. The "code" is a list of instructions that the server should carry out for each member of the arra…