react

"mulling over state management stuff"
lilactown 2021-05-26T01:00:50.029Z

@martinklepsch I’ve been working on https://github.com/lilactown/flex/tree/main/packages/flex-core when I have time which is v advanced, v alpha but sounds more like what you’re looking for. it might inspire you

lilactown 2021-05-26T01:02:56.029300Z

mostly it is v slow 😅

martinklepsch 2021-05-26T09:46:41.032600Z

@lilactown interesting, thanks! that looks very similar to derivatives in that they’re both attempting to implement some kind of incremental dataflow. I haven’t thought about scheduling much at all tbh but a lot of this makes sense to me.

martinklepsch 2021-05-26T09:47:06.033300Z

What makes it so slow? the basic design would make me think it should be fast?

martinklepsch 2021-05-26T09:53:22.035600Z

The https://github.com/martinklepsch/derivatives/blob/master/src/org/martinklepsch/derivatives.cljc is 120 lines if you ignore some of the fringes but it’s all synchronous(?) via add-watch! and I am not doing anything special to order/batch updates. I think the ordering should mostly work though since the low level computations are updated first, then the ones that depend on those etc.

lilactown 2021-05-26T17:25:46.038300Z

There are multiple slow parts I think. The part that stands out to me, if memory serves, is the calculate! function used to calculate and set the new state and dependents of each computation

lilactown 2021-05-26T17:25:56.038700Z

that and the heap algorithm I use to order updates

lilactown 2021-05-26T17:27:29.040Z

the heap is important for ordering because even if you do what you’re saying (breadth first) you can end up in diamond dependencies that require extra work

lilactown 2021-05-26T17:28:45.041300Z

there’s an inherent cost to the way flex stores state in a dynamic variable that will always be slower than storing the state on the computation object itself

lilactown 2021-05-26T17:29:06.041800Z

i.e. every dereference requires a lookup in this dynamic var

lilactown 2021-05-26T17:30:25.043500Z

my hypothesis is I can get it Fast Enough:tm: that the flexibility of being able to use multiple environments for e.g. testing, or reusing computations between different parts of a system, is worth it

2021-05-26T18:31:41.047300Z

at Pitch we are using re-frame, but it shows its weakness due to the nature of dataflow in the app: since Pitch is collaborative realtime app we are sending data events between clients, the whole state of user’s workspace is calculated out of atomic objects (folder, presentation, user, permission, font, style, etc. records). When there’s a new object in memory re-frame has to recalculate related indexes from scratch. While that still works to prevent change propagation in subscriptions graph, recalculating indexes is still quite expensive.

2021-05-26T18:32:52.048200Z

in our case ideally we want some sort of incrementality when calculating derived state

1💯
2021-05-26T18:38:59.051Z

we are also exploring a completely diff approach: event based state updates, basically Kafka on the frontend where instead of randomly writing into an app db and relying on subs graph to figure out what changed, we would update state atomically based on events signalling what exactly is about to change (what type of an object is added/updated/removed)

2021-05-26T18:40:51.052200Z

my conclusion so far is that change inference via subs graph doesn’t scale well in terms of performance, but it’s very easy to use

martinklepsch 2021-05-26T18:41:24.052700Z

The Kafka/change feed approach is also something I’ve been thinking about

martinklepsch 2021-05-26T18:44:08.055200Z

One problem with it is a bit that it’s nice for lists of similar entities but probably a bit trickier for “streams” that combine data from multiple sources. Like ad-hoc subscriptions become harder

lilactown 2021-05-26T18:44:14.055400Z

the tricky part of using an event ledger is that your events need to be fine grained enough to allow change detection to be precise

martinklepsch 2021-05-26T18:44:29.055900Z

Would be very interested to have a chat about this with some folks some time if you’re down 🙂

lilactown 2021-05-26T18:44:34.056100Z

ah I think we just said similar thing :D

martinklepsch 2021-05-26T18:44:56.056500Z

We can upload it to youtube afterwards or something 😄

lilactown 2021-05-26T18:45:16.056900Z

I wish I had time today

lilactown 2021-05-26T18:45:48.057600Z

I think the timely-dataflow / differential-dataflow stuff is the state of the art here

1👀
lilactown 2021-05-26T18:50:49.059900Z

IIRC it combines a log of changes a la kafka with a dataflow graph to allow far more efficient (CPU time) of incremental computations at the cost of additional memory

lilactown 2021-05-26T18:50:56.060200Z

it’s been a little bit since I read the paper

danieroux 2021-05-26T18:58:13.063200Z

If I was to start a multi-user UI collaboration project, I would have a hard look at https://croquet.io/sdk/docs - it use to be a 3D peer-to-peer world implementation in Smalltalk - https://web.archive.org/web/20090220083519/http://www.croquetconsortium.org/images/2/2b/2003_Croquet_Collab_Arch.pdf

danieroux 2021-05-26T18:58:23.063400Z

Croquet is a synchronization system for multiuser digital experiences. It allows multiple users to work or play together within a single shared distributed environment, and it guarantees that this distributed environment will remain bit-identical for every user.”

danieroux 2021-05-26T19:09:28.063700Z

Yay, finding myself in a new/old rabbit hole: https://www.youtube.com/watch?v=9xWDTwdqfno