4 ms·
In my case, I’ve built Python applications that poll multiple sensor data, perform calculations, and push results to the frontend. The frontend is also allowed
by buibuibui 2y ago
In my case, I’ve built Python applications that poll multiple sensor data, perform calculations, and push results to the frontend. The frontend is also allowed to configure the measurements on the fly, so I needed some form of reactivity in my backend to handle dynamic changes smoothly.
Could you share an example of the problem you’re referring to?
- jitl 2y agoI didn’t have time to work up a repro, but the issue is a classic one with the basic algorithm you use for your ComputeSignal graph. The issue is that during the fan-out after a change at a root, a ComputeSignal that’s recomputing can read a stale out of date value from a ComputeSignal that has not yet recomputed for the change. The simplest solution to implement is to do two phase propagation, the first phase marks all ComputeSignal as “dirty” so any read of them must re-compute. Then in the second phase you do what you’re already doing which is to walk down, re-computing, and stop at ComputeSignals that didn’t change. There are other approaches like using a logical clock that have different balances between time complexity at write time and time complexity at read time. Besides the correctness issue, the eager depth first strategy can re-compute the same ComputeSignal multiple times for a single change to a root. This can also be solved with the dirty phase, because once a dirty ComputeSignal becomes clean you don’t need to re-compute it again during that write’s fan-out.
- jitl 2y agoShiny from the above commenter is a good example of the dirty / “invalidate” style of algorithm. https://github.com/posit-dev/py-shiny/blob/main/shiny/reactive/_reactives.py https://github.com/posit-dev/py-shiny/blob/main/shiny/reacti... https://github.com/posit-dev/py-shiny/blob/main/shiny/reactive/_core.py https://github.com/posit-dev/py-shiny/blob/main/shiny/reacti...