From cf15afaa350d99a5c72700b46159eb27a8e38be2 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Wed, 3 Apr 2024 17:57:45 +0200 Subject: [PATCH 1/6] add background field --- src/app/callbacks.jl | 16 ++++++++++------ src/app/supporttypes.jl | 1 + test/callbacks.jl | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/app/callbacks.jl b/src/app/callbacks.jl index 314a6d8..c05f8c2 100644 --- a/src/app/callbacks.jl +++ b/src/app/callbacks.jl @@ -60,9 +60,9 @@ function callback!(func::Union{Function, ClientsideFunction, String}, output::Union{Vector{<:Output}, Output}, input::Union{Vector{<:Input}, Input}, state::Union{Vector{<:State}, State} = State[]; - prevent_initial_call = nothing + kwargs... ) - return _callback!(func, app, CallbackDeps(output, input, state), prevent_initial_call = prevent_initial_call) + return _callback!(func, app, CallbackDeps(output, input, state); kwargs...) end """ @@ -99,13 +99,13 @@ end function callback!(func::Union{Function, ClientsideFunction, String}, app::DashApp, deps::Dependency...; - prevent_initial_call = nothing + kwargs... ) output = Output[] input = Input[] state = State[] _process_callback_args(deps, (output, input, state)) - return _callback!(func, app, CallbackDeps(output, input, state, length(output) > 1), prevent_initial_call = prevent_initial_call) + return _callback!(func, app, CallbackDeps(output, input, state, length(output) > 1); kwargs...) end function _process_callback_args(args::Tuple{T, Vararg}, dest::Tuple{Vector{T}, Vararg}) where {T} @@ -124,7 +124,10 @@ function _process_callback_args(args::Tuple{}, dest::Tuple{}) end -function _callback!(func::Union{Function, ClientsideFunction, String}, app::DashApp, deps::CallbackDeps; prevent_initial_call) +function _callback!(func::Union{Function, ClientsideFunction, String}, app::DashApp, deps::CallbackDeps; + prevent_initial_call = nothing, + background = false, + manager = nothing) check_callback(func, app, deps) @@ -138,7 +141,8 @@ function _callback!(func::Union{Function, ClientsideFunction, String}, app::Dash deps, isnothing(prevent_initial_call) ? get_setting(app, :prevent_initial_callbacks) : - prevent_initial_call + prevent_initial_call, + background ) ) end diff --git a/src/app/supporttypes.jl b/src/app/supporttypes.jl index dd913c6..1d05847 100644 --- a/src/app/supporttypes.jl +++ b/src/app/supporttypes.jl @@ -112,6 +112,7 @@ struct Callback func ::Union{Function, ClientsideFunction} dependencies ::CallbackDeps prevent_initial_call ::Bool + background ::Bool end is_multi_out(cb::Callback) = cb.dependencies.multi_out == true diff --git a/test/callbacks.jl b/test/callbacks.jl index 2b8f6bd..3c9dc4a 100644 --- a/test/callbacks.jl +++ b/test/callbacks.jl @@ -657,3 +657,21 @@ end @test occursin("clientside[\"_dashprivate_my-div\"]", body) @test occursin("ns[\"children\"]", body) end + +@testset "Background callbacks" begin + app = dash() + app.layout = html_div() do + html_div(html_p(id = "paragraph_id", children = ["Button not clicked"])) + html_button(id="buttton_id", children = "Run Job!") + end + + callback!(app, Output("paragraph_id", "children"), Input("button_id", "n_clicks"), background = true) do clicks + sleep(2) + return string("Clicked ", clicks, " times") + end + + handler = make_handler(app) + request = HTTP.Request("GET", "/_dash-dependencies") + resp = Dash.HttpHelpers.handle(handler, request) + deps = JSON3.read(String(resp.body)) +end \ No newline at end of file From 4530994892ad7a4fa455d2c1cada983da87344c3 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Thu, 4 Apr 2024 16:35:40 +0200 Subject: [PATCH 2/6] pass stuff to json output --- src/app/callbacks.jl | 4 +++- src/app/supporttypes.jl | 3 ++- src/handler/state.jl | 3 ++- test/callbacks.jl | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/callbacks.jl b/src/app/callbacks.jl index c05f8c2..eb59bd7 100644 --- a/src/app/callbacks.jl +++ b/src/app/callbacks.jl @@ -127,6 +127,7 @@ end function _callback!(func::Union{Function, ClientsideFunction, String}, app::DashApp, deps::CallbackDeps; prevent_initial_call = nothing, background = false, + interval = 1000, manager = nothing) check_callback(func, app, deps) @@ -142,7 +143,8 @@ function _callback!(func::Union{Function, ClientsideFunction, String}, app::Dash isnothing(prevent_initial_call) ? get_setting(app, :prevent_initial_callbacks) : prevent_initial_call, - background + background, + interval ) ) end diff --git a/src/app/supporttypes.jl b/src/app/supporttypes.jl index 1d05847..396a8db 100644 --- a/src/app/supporttypes.jl +++ b/src/app/supporttypes.jl @@ -112,7 +112,8 @@ struct Callback func ::Union{Function, ClientsideFunction} dependencies ::CallbackDeps prevent_initial_call ::Bool - background ::Bool + long ::Bool + interval ::Int end is_multi_out(cb::Callback) = cb.dependencies.multi_out == true diff --git a/src/handler/state.jl b/src/handler/state.jl index 56232ce..68ff7d8 100644 --- a/src/handler/state.jl +++ b/src/handler/state.jl @@ -30,7 +30,8 @@ function _dependencies_json(app::DashApp) state = dependency_tuple.(callback.dependencies.state), output = output_string(callback.dependencies), clientside_function = _dep_clientside_func(callback.func), - prevent_initial_call = callback.prevent_initial_call + prevent_initial_call = callback.prevent_initial_call, + long = callback.long && (interval = callback.interval) ) end return JSON3.write(result) diff --git a/test/callbacks.jl b/test/callbacks.jl index 3c9dc4a..e71f3a5 100644 --- a/test/callbacks.jl +++ b/test/callbacks.jl @@ -674,4 +674,5 @@ end request = HTTP.Request("GET", "/_dash-dependencies") resp = Dash.HttpHelpers.handle(handler, request) deps = JSON3.read(String(resp.body)) + @test deps[1].long end \ No newline at end of file From 09001934e15c55504bb117f729f9549a1dc5f109 Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 26 Apr 2024 17:46:05 +0200 Subject: [PATCH 3/6] add keywords --- src/app/callbacks.jl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/callbacks.jl b/src/app/callbacks.jl index eb59bd7..e900b10 100644 --- a/src/app/callbacks.jl +++ b/src/app/callbacks.jl @@ -128,7 +128,13 @@ function _callback!(func::Union{Function, ClientsideFunction, String}, app::Dash prevent_initial_call = nothing, background = false, interval = 1000, - manager = nothing) + manager = nothing, + progress = nothing, + progress_default = nothing, + running = nothing, + cancel = nothing, + cache_args_to_ignore = nothing + ) check_callback(func, app, deps) From 5d79fb9c56d7b5330fbcd4952e63cb066205ebfa Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 26 Apr 2024 17:46:15 +0200 Subject: [PATCH 4/6] add cache types --- src/handler/state.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/handler/state.jl b/src/handler/state.jl index 68ff7d8..d05d172 100644 --- a/src/handler/state.jl +++ b/src/handler/state.jl @@ -21,6 +21,11 @@ mutable struct StateCache StateCache(app, registry) = new(_cache_tuple(app, registry)..., false) end +abstract type BackgroundCallBackManager end + +mutable struct DiskcacheManager <: BackgroundCallBackManager +end + _dep_clientside_func(func::ClientsideFunction) = func _dep_clientside_func(func) = nothing function _dependencies_json(app::DashApp) From 29534f0517293523f4defc513049f5ec62fb9acf Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 26 Apr 2024 18:12:48 +0200 Subject: [PATCH 5/6] copy long_spec --- src/app/callbacks.jl | 13 +++++++++++-- src/app/supporttypes.jl | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app/callbacks.jl b/src/app/callbacks.jl index e900b10..2ecf2f5 100644 --- a/src/app/callbacks.jl +++ b/src/app/callbacks.jl @@ -138,6 +138,16 @@ function _callback!(func::Union{Function, ClientsideFunction, String}, app::Dash check_callback(func, app, deps) + if background + long_spec = Dict(:interval => interval) + manager !== nothing && (long_spec[:manager] = manager) + progress !== nothing && (long_spec[:progress] = progress) + progress_default !== nothing && (long_spec[:progress_default] = progress_default) + running !== nothing && (long_spec[:running] = running) + cancel !== nothing && (long_spec[:cancel] = cancel) + cache_args_to_ignore !== nothing && (long_spec[:cache_args_to_ignore] = cache_args_to_ignore) + end + out_symbol = Symbol(output_string(deps)) haskey(app.callbacks, out_symbol) && error("Multiple callbacks can not target the same output. Offending output: $(out_symbol)") callback_func = make_callback_func!(app, func, deps) @@ -149,8 +159,7 @@ function _callback!(func::Union{Function, ClientsideFunction, String}, app::Dash isnothing(prevent_initial_call) ? get_setting(app, :prevent_initial_callbacks) : prevent_initial_call, - background, - interval + background ? long_spec : background ) ) end diff --git a/src/app/supporttypes.jl b/src/app/supporttypes.jl index 396a8db..f48a55e 100644 --- a/src/app/supporttypes.jl +++ b/src/app/supporttypes.jl @@ -112,8 +112,8 @@ struct Callback func ::Union{Function, ClientsideFunction} dependencies ::CallbackDeps prevent_initial_call ::Bool - long ::Bool - interval ::Int + # TODO: refine Any s when done + long ::Any end is_multi_out(cb::Callback) = cb.dependencies.multi_out == true From 1041519012967c7c8575051953ce01d402b50bfb Mon Sep 17 00:00:00 2001 From: Simon Christ Date: Fri, 3 May 2024 16:44:09 +0200 Subject: [PATCH 6/6] fix tests --- src/handler/state.jl | 2 +- test/callbacks.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/handler/state.jl b/src/handler/state.jl index d05d172..20d1d32 100644 --- a/src/handler/state.jl +++ b/src/handler/state.jl @@ -36,7 +36,7 @@ function _dependencies_json(app::DashApp) output = output_string(callback.dependencies), clientside_function = _dep_clientside_func(callback.func), prevent_initial_call = callback.prevent_initial_call, - long = callback.long && (interval = callback.interval) + long = callback.long !== false && (interval = callback.long[:interval],) ) end return JSON3.write(result) diff --git a/test/callbacks.jl b/test/callbacks.jl index e71f3a5..70952b2 100644 --- a/test/callbacks.jl +++ b/test/callbacks.jl @@ -674,5 +674,5 @@ end request = HTTP.Request("GET", "/_dash-dependencies") resp = Dash.HttpHelpers.handle(handler, request) deps = JSON3.read(String(resp.body)) - @test deps[1].long + @test deps[1].long.interval == 1000 end \ No newline at end of file