Hacker News new | ask | show | jobs
by karthikksv 2213 days ago
I had this same inspiration from Chris McCord's talk about LiveView ~1.5 years back, and created Purview: https://github.com/karthikv/purview - we've been using it in production at the company I work at for over a year now.

It's great to see a similar mindset here, and I hope an approach like this becomes more widely used. I appreciate how Caldera is built using React's reconciler and is centered around hooks, both of which are different than the approach Purview takes.

Two of the challenges we've experienced here:

- Transferring server-side state between processes: in production, you'll likely have multiple Node processes handling requests via the cluster module or other load balancing. If a client were to disconnect their websocket temporarily (e.g. put their laptop to sleep), they can be reconnected to a different process, which doesn't have the state of their components. As a result, you'll need some way to transfer/persist component state between processes. This same issue will also arise during deploys--you'll spawn new processes with your new code, but you don't want to disrupt existing clients, so those new processes need to load existing component state from old processes. Even more subtly, this issue can occur on page load, since two requests need to be made: one to fetch the initial page and one to initiate the websocket connection. Those two requests can be sent to two different processes/boxes.

- Working with existing client-side libraries, like selectize or date range pickers. We've opted to use the Web Component spec to create custom tags that can be sent down just like normal tags from the server, but making sure these interoperate nicely with server-side state is challenging.

Very excited to see how Caldera tackles these problems!

2 comments

Great minds think alike! I had a feeling this was a relatively straightforward insight, and Purview looks like a pretty cool implementation.

To answer your questions:

1. We have a mechanism to serialize the React state tree, as long as it can be copied with the HTML structured clone algorithm (https://github.com/calderajs/caldera-react/blob/master/src/s...) which has always seemed to be the case in practice. Each tree is associated with a unique token which is stored on the client, but the current storage implementation is in-memory only as we haven't addressed the application upgrade issue. Outside of that, there's nothing stopping us from adding basic versioning (along with react-hot-loader-like reconciliation behavior) and moving the state storage to a database that is shared among application servers.

2. This isn't really fleshed out yet, but we'd likely take inspiration from React Native's native module approach where lifecycle events for mounting/unmounting/updating a component are implemented on the client, with bindings being called in the server application code (a React-specific version of your web component implementation). I know we're against high-level RPC, but React props naturally have a data/async callback structure that is amenable to being represented as RPC calls (which works for React Native), which is why we're leaning towards that approach.

For the first problem what about the option of making the session:backend-instance mapping sticky? Seems it could be simpler than the implementing the state handover.