-
-
Notifications
You must be signed in to change notification settings - Fork 40
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
Hot reload #25
Hot reload #25
Conversation
Co-authored-by: Ryan Patrick Kyle <rpkyle@users.noreply.github.com>
@waralex I also wanted to mention that we seem to handle interrupts within the REPL a little differently (or Julia does) than those sent while a process is invoked from the CLI: rpkyle$ julia test.jl
[ Info: Running on http://127.0.0.1:8050
^C
signal (2): Interrupt: 2
in expression starting at /private/tmp/testapp/test.jl:27
fatal: error thrown and no exception handler available.
InterruptException()
kevent at /usr/lib/system/libsystem_kernel.dylib (unknown line)
unknown function (ip: 0x0)
Allocations: 18621645 (Pool: 18617092; Big: 4553); GC: 18
jl_mutex_unlock at /Users/julia/buildbot/worker/package_macos64/build/src/./locks.h:143 [inlined]
jl_task_get_next at /Users/julia/buildbot/worker/package_macos64/build/src/partr.c:451
signal (15): Terminated: 15
in expression starting at /private/tmp/testapp/test.jl:27 I'm not sure why this interrupt isn't caught by the exception handler you've already written, but it would be good to provide our own custom message (like |
@waralex I'm not sure if it's related to the revised reloading approach, but I'm seeing an intermittent error related to rpkyle$ julia test_reload.jl
[ Info: Running on http://127.0.0.1:8050
┌ Error: error handling request
│ exception =
│ IOError: stream is closed or unusable
│ Stacktrace:
│ [1] check_open at ./stream.jl:328 [inlined]
│ [2] uv_write_async(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:961
│ [3] uv_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:924
│ [4] unsafe_write(::Sockets.TCPSocket, ::Ptr{UInt8}, ::UInt64) at ./stream.jl:1007
│ [5] unsafe_write at /Users/rpkyle/.julia/packages/HTTP/GkPBm/src/ConnectionPool.jl:174 [inlined]
│ [6] unsafe_write at ./io.jl:593 [inlined]
│ [7] write at ./io.jl:616 [inlined]
│ [8] startwrite(::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /Users/rpkyle/.julia/packages/HTTP/GkPBm/src/Streams.jl:87
│ [9] handle(::HTTP.Handlers.RequestHandlerFunction{Dash.var"#52#53"{Array{String,1},Int64,HTTP.Handlers.RequestHandlerFunction{Dash.var"#49#50"{Dash.Router,Dash.HandlerState}}}}, ::HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}) at /Users/rpkyle/.julia/packages/HTTP/GkPBm/src/Handlers.jl:278
│ [10] #4 at /Users/rpkyle/.julia/packages/HTTP/GkPBm/src/Handlers.jl:345 [inlined]
│ [11] macro expansion at /Users/rpkyle/.julia/packages/HTTP/GkPBm/src/Servers.jl:367 [inlined]
│ [12] (::HTTP.Servers.var"#13#14"{HTTP.Handlers.var"#4#5"{HTTP.Handlers.RequestHandlerFunction{Dash.var"#52#53"{Array{String,1},Int64,HTTP.Handlers.RequestHandlerFunction{Dash.var"#49#50"{Dash.Router,Dash.HandlerState}}}}},HTTP.ConnectionPool.Transaction{Sockets.TCPSocket},HTTP.Streams.Stream{HTTP.Messages.Request,HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})() at ./task.jl:358
└ @ HTTP.Servers ~/.julia/packages/HTTP/GkPBm/src/Servers.jl:373 |
Apparently, this should be solved in the future PR with logging and exception handling. The error itself most likely occurs when the client close the connection before receiving a response from the server |
I have refused to use |
Co-authored-by: Ryan Patrick Kyle <rpkyle@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@waralex Great, I think this is OK to merge into dev
, pending two minor comments:
- we currently have an
@warn
message for hot reloading on L139 ofsrc/Dash.jl
, but anerror
with a similar message on L6 ofsrc/utils/hot_restart.jl
. Is this OK? We could exit thehot_restart.jl
function after throwing a@warn
there, it doesn't have to be anerror
to interrupt function execution since it's wrapped inif ...end
, we can back out within that statement if we wish. - this feature needs a
CHANGELOG.md
entry, as do all new features 🙂 I'll commit the currentCHANGELOG.md
revision fromdev
to this branch, so you can do that.
Otherwise, when done, I'd say 💃 . LGTM!
src/utils/hot_restart.jl
Outdated
end | ||
function hot_restart(func::Function; check_interval = 1., env_key = "IS_HOT_RELOADABLE", suppress_warn = false) | ||
if !is_hot_restart_available() | ||
error("hot restart is disabled for intereactive sessions") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error("hot restart is disabled for intereactive sessions") | |
error("hot restart is disabled for interactive sessions") |
The difference is that in src/Dest.jl we show the warning and execute the if / else branch that doesn't use the |
done in 921e3e4 |
Labeler failure is likely related to ongoing GitHub issues this afternoon, so will merge as soon as CI test passes; no failures upon disabling Labeler. |
Proposed in this PR:
name
argument indash()
has been deletedDash for Python's "hot-reloading" feature is described in plotly/dash#66, plotly/dash#362, and plotly/dash-renderer#73.
Supporting this as in the Python and R implementations would require
dev_tools_hot_reload
,dev_tools_hot_reload_interval
,dev_tools_hot_reload_watch_interval
,dev_tools_silence_routes_logging
On the Python side, we use the Flask debug reloader to reset the hash. We would need to find a comparable approach using HTTP.jl instead.