Skip to content
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

Server-side events as configuration #1871

Merged
merged 6 commits into from
Feb 1, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Configuration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ The HTTP server options. See [`SecurityOptions`](@ref) for additional settings.
notebook::Union{Nothing,String,Vector{<:String}} = nothing
init_with_file_viewer::Bool = false
simulated_lag::Real = 0.0
on_event::Function = function(a) #= @info "$(typeof(a))" =# end
end

"""
Expand Down
33 changes: 16 additions & 17 deletions src/notebook/Events.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,36 @@ the FileSaveEvent may be triggered whenever pluto wants to make sure the file is
which may be more often than the file is actually changed. Deduplicate on your own if
you care about this.

To use that, we assume you are running Pluto through a julia script and
opening it as

julia > pluto_server_session = Pluto.ServerSession(;
secret = secret,
options = pluto_server_options,
)

Define your function to handle the events using multiple dispatch:

First assign a handler for all the types you will not use, using the supertype:

julia > function myfn(a::PlutoEvent)
nothing
end
```julia-repl
julia> function myfn(a::PlutoEvent)
nothing
end
```


And then create a special function for each event you want to handle specially

julia > function myfn(a::FileSaveEvent)
HTTP.post("https://my.service.com/count_saves")
end
```julia-repl
julia> function myfn(a::FileSaveEvent)
HTTP.post("https://my.service.com/count_saves")
end
```

Finally, assign the listener to your session
Finally, pass the listener to Pluto's configurations with a keyword argument

julia > pluto_server_session.event_listener = yourfunction
```julia-repl
julia> Pluto.run(; on_event = myfn)
```
"""
abstract type PlutoEvent end

function try_event_call(session, event::PlutoEvent)
return try
session.event_listener(event)
session.options.server.on_event(event)
catch e
@warn "Couldn't run event listener" event exception=(e, catch_backtrace())
nothing
Expand Down
4 changes: 4 additions & 0 deletions src/webserver/MsgPack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ MsgPack.msgpack_type(::Type{Configuration.CompilerOptions}) = MsgPack.StructType
MsgPack.msgpack_type(::Type{Configuration.ServerOptions}) = MsgPack.StructType()
MsgPack.msgpack_type(::Type{Configuration.SecurityOptions}) = MsgPack.StructType()

# Don't try to send callback functions which can't be serialized (see ServerOptions.event_listener)
MsgPack.msgpack_type(::Type{Function}) = MsgPack.NilType()
MsgPack.to_msgpack(::MsgPack.NilType, ::Function) = nothing

# We want typed integer arrays to arrive as JS typed integer arrays:
const JSTypedIntSupport = [Int8, UInt8, Int16, UInt16, Int32, UInt32, Float32, Float64]
JSTypedInt = Union{Int8,UInt8,Int16,UInt16,Int32,UInt32,Float32,Float64}
Expand Down
1 change: 0 additions & 1 deletion src/webserver/Session.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ Base.@kwdef mutable struct ServerSession
secret::String = String(rand(('a':'z') ∪ ('A':'Z') ∪ ('0':'9'), 8))
binder_token::Union{String,Nothing} = nothing
options::Configuration.Options = Configuration.Options()
event_listener::Function = function(a::PlutoEvent) #= @info "$(typeof(a))" =# end
end

function save_notebook(session::ServerSession, notebook::Notebook)
Expand Down
1 change: 1 addition & 0 deletions src/webserver/WebServer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ function run(session::ServerSession, pluto_router)
hostIP = parse(Sockets.IPAddr, host)
if port === nothing
port, serversocket = Sockets.listenany(hostIP, UInt16(1234))
session.options.server.port = port
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this because otherwise server-side event consumers would have no way of knowing what port Pluto is running on. This would only assign the configured port when it is not explicitly provided.

else
try
serversocket = Sockets.listen(hostIP, UInt16(port))
Expand Down