JuliaGizmos / WebIO.jl

A bridge between Julia and the Web.
https://juliagizmos.github.io/WebIO.jl/latest/
Other
228 stars 64 forks source link

Allow scope/observable reaping #321

Open twavv opened 5 years ago

twavv commented 5 years ago

Currently, we keep track of all scopes that have ever been created. This is bad news bears for memory management.

It tends to work well in situations like a Jupyter notebook where the process is relatively short-lived (and Jupyter has it's own memory issues as well because it keeps track of every single output until the end of time), but less well for things like a webserver.

The underlying issue is that we're never sure when a frontend has a reference to a scope (any frontend could issue a setup scope command for any scope that might have used to exist - eg. after reconnecting to wifi). In the case of Mux, we would just have the client refresh so it's not that big of an issue.

Proposal

Implement a timeout system for purging scopes (e.g. if a scope hasn't been connected to in ten minutes, delete it). This must be configurable and probably should default to ever expiring since that's the current behavior. We also should also implement a way for the browser to tell Julia that it's done with a scope (this should be a second/separate PR).

We'd also need some kind of liveness probe for all of the active connections (maybe - the TCP connection dropping might be good enough for us to get a signal from?). We just don't want zombie connections to keep scopes persisted.

This would also WebIO-built things to be a bit more general purpose (e.g. internal web interfaces). I'm still not comfortable with writing public facing products using WebIO but this would better enable a certain use case.

Steps

twavv commented 5 years ago

@shashi and I talked at JuliaCon.

Think the best thing to do is have a WeakRefDict from connections to scopes and make the global_scope_dict entries WeakRefs as well. This should allow scopes to be GC'd by Julia when the connections go away.

We need a way to make sure that IJulia can hold on to the references forever though (maybe a callback that can be registered for whenever a Scope is constructed).

Optionally, we could implement a way to ping the connection from Julia and make sure it's still alive. This might not be necessary.

twavv commented 5 years ago

Something like this?

# In IJulia provider
scopes = Vector{Scope}[]
on_scope_create!() do scope
  push!(scopes, scope)
end

We can also implement explicit scope removal.

E.g. when a cell is re-run, the browser can send a teardown_scope message which says delete the scope if there are no more connections.