Live data from Hacker News

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

blog.cloudflare.com

271–280 of 305 posts

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

#271

Earlier quoted context omitted.

Is there anything C# _doesn’t_ have? :-) It feels like C# has an answer to every problem I’ve ever had with other languages - dynamic loading, ADTs with pattern matching, functional programming, whatever this expression tree is, reflection, etc etc. Yet somehow it’s still a niche language that isn't widely used (outside of particular ecosystems).

As someone who dislikes clutter, in my experience it's just easier to read and write with these languages: Perl, PHP, Ruby, Python, Javascript, Smalltalk. If you dare leave the safety of a compiler you'll find that Sublime Merge can still save you when rewriting a whole part of an app. That and manual testing (because automatic testing is also clutter). If you think it's more professional to have a compiler I'd like…

I'm a bit surprised that you put PHP in that list. My current workload is in it, and a relatively modern version of it, so maybe that surprise will turn around soon, but I've always felt that PHP was more obnoxious than even C to read and write.

Granted, I started out on LISP. My version of "easy to read and write" might be slightly masochistic. But I love Perl and Python and Javascript are definitely "you can jump in and get shit done if you have worked in most languages. It might not be idiomatic, but it'll work"...

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

#273

Earlier quoted context omitted.

The protocol itself is really only language-specific to a similar extent that JSON is language-specific. Which you can totally argue it is, but also people have figured out how to use it in lots of languages other than JavaScript. I think Cap'n Web could work pretty well in Python and other dynamically-typed languages. Statically-typed would be a bit trickier (again, in the same sense that they are harder to use JSON…

Retrofitting to some but not all languages is not nearly the same as an intentionally language agnostic protocol. To the extent that calling this "web" is at best misleading.

Which part of the protocol do you think is actually specific to JavaScript?

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

#274

Earlier quoted context omitted.

I said that shared state between connections is rare, but shared state within a connection is extremely common. And there are still multiple concurrent things going on within that connection context, requiring some concurrency mechanism. Locking mutexes everywhere sounds like a nightmare to me.

Ah I see. Well that is typically just fan-out-fan-in like "run these 4 SQL queries and RPCs in parallel and collect responses," nothing too complicated since the shared resources like the DB handle are usually thread-safe. It works out fine in Go and Java, even though I have unrelated reasons to avoid Go.

“Running 4 SQL queries in parallel” is not thread-safe if done in separate transactions, and on data that is not read-only.

If some other transaction commits at just the wrong time, it could change the result of some of these queries but not all. The results would not be consistent with each other.

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

#275
post #212

Earlier quoted context omitted.

I totally agree with your framing of the value of async/await, but could you elaborate more on why you think that this behavior (which I would call "cooperative concurrency") is important for (ocap?) RPC systems? It seems to me that preemptive concurrency also suffices to make RPC viable. Unless you just feel that preemptive concurrency is too hard, and therefore not workable for RPC systems?

Almost all ocap systems seem to use event loops -- and many of the biggest ocap nerds I know are also the biggest event loop nerds I know. I'm not actually sure if this is a coincidence or if there's something inherent that makes it necessary to pair them. But one thing I can't figure out: What would be the syntax for promise pipelining, if you aren't using promises to start with?

>What would be the syntax for promise pipelining, if you aren't using promises to start with?

Oh, great point! That does seem really hard, maybe even intractable. That's definitely a reason to like cooperative concurrency, huh...

Just to tangent even further, but some ideas:

- Do it the ugly way: add an artificial layer of promises in an otherwise pre-emptive, direct-style language. That's just, unfortunately, quite ugly...

- Use a lazy language. Then everything's a promise! Some Haskell optimizations feel kind of like promise pipelining. But I don't really like laziness...

- Use iterator APIs; that's a slightly less artificial way to add layers of promises on top of things, but still weird...

- Punt to the language: build an RPC protocol into the language, and promise pipelining as a guaranteed optimization. Pretty inflexible, and E already tried this...

- Something with choreographic programming and modal-types-for-mobile-code? Such languages explicitly track the "location" of values, and that might be the most natural way to represent ocap promises: a promise is a remote value at some specific location. Unfortunately these languages are all still research projects...

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

#276

I've built similar things in the past. (And apologies for merely skimming the article.) In general, I worry that framework frameworks like this could be horribly complex; breaking bugs (in the framework) might not show up until late in your development cycle. This could mean that you end up having to rewrite your product sooner than you would like, or otherwise "the framework gets in the way" and cripples product dev…

I should have added: One of the advantages of server-side Blazor (in C#) is that the server essentially returns partial bits of HTML for incremental page updates. This allows you to write UI code without needing to jump through all the hoops of creating a full API between your UI and server.

(IE, you can write quick-and-dirty pages where the UI directly queries the database. Useful for one-offs, prototypes, internal admin pages, "KISS" applications, ect, ect. IE, any situation where it's okay for the browser UI to be tightly coupled to your data model.)

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

#277
post #213

Earlier quoted context omitted.

Also, your function needs to be very careful on closures. Date.toLocaleString and many other js functions will be different on client and server, which will also cause silent corruption.

If you invoke `Date.toLocaleString()` in a map callback, it will consistently always run on the client.

I don't see how this very contrived example pipelines:

    client.getAll({userIds}).map((user) => user.updatedAt == new Date().toLocaleString() ? client.photosFor(user.id) : {})
or without the conditional,

    client.getAll({userIds}).map((user) => client.photos({userId: user.id, since: new Date(user.updatedAt).toLocaleString()})
Like it has to call toLocaleString on the server, no?

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

#278

Earlier quoted context omitted.

Ah I see. Well that is typically just fan-out-fan-in like "run these 4 SQL queries and RPCs in parallel and collect responses," nothing too complicated since the shared resources like the DB handle are usually thread-safe. It works out fine in Go and Java, even though I have unrelated reasons to avoid Go.

“Running 4 SQL queries in parallel” is not thread-safe if done in separate transactions, and on data that is not read-only. If some other transaction commits at just the wrong time, it could change the result of some of these queries but not all. The results would not be consistent with each other.

Thread-safe just means that the threading by itself doesn't break anything. The race condition you're describing is outside this scope and would happen the same in a single-threaded event loop.

Btw if you really want consistent multi reads, some DBMSes support setting a read timestamp, but the common ones don't.

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

#279
Yesterday, I migrated my web worker codes from Comlink to CapnWeb. I had extensive experience with Cloudflare Worker bindings, and as mentioned in the original post, they were quite similar.

Everything appears to be functioning smoothly, but I do miss the ‘transfer’ feature in Comlink. Although it wasn’t a critical feature, it was a nice one.

The best aspect of CapnWeb is that we can reuse most of the code related to clients, servers, and web workers (including Cloudflare Workers).

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

#280
post #277

Earlier quoted context omitted.

If you invoke `Date.toLocaleString()` in a map callback, it will consistently always run on the client.

I don't see how this very contrived example pipelines: client.getAll({userIds}).map((user) => user.updatedAt == new Date().toLocaleString() ? client.photosFor(user.id) : {}) or without the conditional, client.getAll({userIds}).map((user) => client.photos({userId: user.id, since: new Date(user.updatedAt).toLocaleString()}) Like it has to call toLocaleString on the server, no?

Neither of these will type check.

You can't perform computation on a promise. The only thing you can do is pipeline on it.

`user.updatedAt == date` is trying to compare a promise against a date. It won't type check.

`new Date(user.updatedAt)` is passing a promise to the Date constructor. It won't type check.

Post reply on HN