-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PureComputedObservable to prevent memory leaks and improve performance? #1
Comments
I thought about this some more, and now I think my approach from Observables2 is also not necessarily a solution. It's problematic that any closure can trigger arbitrary observables, without being registered as a direct input. So the dependency graph I could obtain with my registration approach would still not reflect all the real connections. Example: x = Node(1)
y = Node(2)
z = lift(y) do y
x[] = y + 2 # this connection from y to x would not be registered in Observables2 either, and is hard to detect correctly
y * 2
end Your approach with pure observables sounds interesting for computation pipelines, but for a lot of purposes, purity is not an option if you manipulate tons of plot object attributes. As I see it, one of the main issues now is that it's easy to do something like I think a couple of things could be worth thinking about:
|
There is a fair amount of discussion in JuliaGizmos/Observables.jl#1, which seems exactly the issues you are describing (how Observables plays with garbage collection), esp. JuliaGizmos/Observables.jl#1 (comment) may be useful.
Thinking more about it, it's not exactly about "purity". I suspect that has longs as callbacks are "idempotent" (that is, calling |
Even though it is not the latest or most popular framework, I really like Knockout.js as an inspiration for observables and bindings.
What we are struggling with are, as far as I understand, "computed observables", that is to say
lift(f, obs::Observable...)
. I think that the key issue is that we implementlift
withonany
, and do it eagerly. I'll list below a few more thoughts that hopefully can help.What you have implemented here seems like
ComputedObservable
from Knockout. Given that we have an abstract typeAbstractObservable
in Observables, I think this can peacefully coexist with the oldObservable
(which is the particular case with no inputs). Do you think it's possible to have it respect theObservables.AbstractObservable
interface, while having an explicit list of input functions? I think of it as some sort ofObservable
with extra data. We could then changelift
to actually give you this, rather than the plainObservable
. In its finalizer, it could clear the input function from its input observables as soon as it goes out of scope.OTOH, I believe that the biggest gains are to be had in the case where
f
(the function of the computing observable) is pure, i.e., it has no side effects. There, many optimizations become possible. See pure computed observable in Knockout.I would suggest to try and focus on pure observables, making them lazy somehow. That is to say, the input function would be called only on
getindex
, provided that some of the inputs have changed. These can have no callbacks (or we should make sure that they are eager when they have at least a callback). My hope is that one can make a chain of these lazy pure observables from input to output, and then the drawing would be triggered by the render loop. I've made a POC implementation here, see test file for an example usage.The text was updated successfully, but these errors were encountered: