Live data from Hacker News

Cap'n Web: a new RPC system for browsers and web servers

blog.cloudflare.com

111–120 of 305 posts

Re: Cap'n Web: a new RPC system for browsers and web servers

#111
post #89

Earlier quoted context omitted.

Async/await became ergonomic and widespread only recently, I am sure there were async systems in the '80 but for example nodejs focus on non blocking I/O changed how a lot of people thought about servers and concurrency (whether node was first is almost irrelevant) Often when something is discovered or invented is far less influential[1] than when it jumps on and hype train. [1] the discovery is very important for hi…

It's not a programming paradigm shift, more of a change to how runtimes work. We want to avoid the overhead of kernel threads in servers, and async/await on top of an event loop is a convenient way to do that, like in JS, Rust, and now Python. Meanwhile Go doesn't have async/await and never will because it doesn't need it; it does greenthreading instead. Java has that too now. Either way, your code waits on IO like b…

I disagree that async/await is purely about avoiding overhead of kernel threads. Kernel threads are actually not that expensive these days. You can have a server with 10,000 threads, no problem.

The problem is synchronization becomes extremely hard to reason about. With event loop concurrency, each continuation (callback) becomes effectively a transaction, in which you don't need to worry about anything else modifying your state out from under you. That legitimately makes a lot of things easier.

The Cloudflare Workers runtime actually does both: There's a separate thread for each connection, but within each thread there's an event loop to handle all the concurrent stuff relating to that one connection. This works well because connections rarely need to interact with each other's state, but they need to mess with their own state constantly.

(Actually we have now gone further and stacked a custom green-threading implementation on top of this, but that's really a separate story and only a small incremental optimization.)

Re: Cap'n Web: a new RPC system for browsers and web servers

#112
post #76
post #72

That's more or less a dynamically-typed version of what we had with Opalang ~15 years ago and it worked great. Happy to see that someone else has picked the idea of sending capabilities, including server->client calls!

FWIW, Cap'n Proto is a statically-typed version of this that has been around since 2013, and is actually used heavily in the implementation of Cloudflare Workers.

Ah, thanks, I wasn't aware of that.

That won't prevent me from bragging, as we released Opalang 1.0 in 2011 :)

Re: Cap'n Web: a new RPC system for browsers and web servers

#113
post #112
post #76

Earlier quoted context omitted.

FWIW, Cap'n Proto is a statically-typed version of this that has been around since 2013, and is actually used heavily in the implementation of Cloudflare Workers.

Ah, thanks, I wasn't aware of that. That won't prevent me from bragging, as we released Opalang 1.0 in 2011 :)

I think Mark S Miller beat us both by like 10-20 years with CapTP. ;)

Re: Cap'n Web: a new RPC system for browsers and web servers

#115
post #90
post #57

The 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…

In C#, there's expression trees which handle things like this and it's how Entity Framework is able to convert the lambdas it's given into SQL. This means that you can pass around code that can be inspected or transformed instead of being executed. Take this EntityFramework snippet: db.People.Where(p => p.Name == "Joe") `Where` takes an `Expression > predicate`. It isn't taking the `Func` itself, but an `Expression`…

It dont think C# looks at the code? I suspect it can track that you called p.Name, then generate sql with this information?

Re: Cap'n Web: a new RPC system for browsers and web servers

#116
post #90

Earlier quoted context omitted.

In C#, there's expression trees which handle things like this and it's how Entity Framework is able to convert the lambdas it's given into SQL. This means that you can pass around code that can be inspected or transformed instead of being executed. Take this EntityFramework snippet: db.People.Where(p => p.Name == "Joe") `Where` takes an `Expression > predicate`. It isn't taking the `Func` itself, but an `Expression`…

It dont think C# looks at the code? I suspect it can track that you called p.Name, then generate sql with this information?

The lambda is converted into an Expression, basically a syntax tree, which is then analyzed to see what is accessed.

Re: Cap'n Web: a new RPC system for browsers and web servers

#117
post #98

Earlier quoted context omitted.

What about filter? Seems useful also.

I don't think you could make filter() work with the same approach, because it seems like you'd actually have to do computation on the result. map() works for cases where you don't need to compute anything in the callback, you just want to pipeline the elements into another RPC, which is actually a common case with map(). If you want to filter server-side, you could still accomplish it by having the server explicitly…

But you might want to compose various methods on the server in order to filter, just like you might want to compose various methods on the server in order to transform. Why is `collection.map(server.lookupByInternalizedId)` a special case that doesn't require `server.lookupCollectionByInternalizedId(collection)`, but `collection.filter(server.isOperationSensibleForATuesday)` is a bridge too far and for that you need `server.areOperationsSensibleForATuesday(collection)`?

Re: Cap'n Web: a new RPC system for browsers and web servers

#120
post #57

The 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…

This record and replay trick is very similar to what I recently used to implement the query DSL for Tanstack DB (https://tanstack.com/db/latest/docs/guides/live-queries). We pass a RefProxy object into the where/select/join callbacks and use it to trace all the props and expressions that are performed. As others have noted you can't use js operators to perform actions, so we built a set of small functions that we could trace (eq, gt, not etc.). These callbacks are run once to trace the calls and build a IR of the query.

One thing we were surprisingly able to do is trace the js spread operation as that is a rare case of something you can intercept in JS.

Kenton, if you are reading this, could you add a series of fake operators (eq, gt, in etc) to provide the capability to trace and perform them remotely?

Post reply on HN