diff --git a/src/app/callbacks.jl b/src/app/callbacks.jl index 314a6d8..2ecf2f5 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,10 +124,30 @@ 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, + interval = 1000, + manager = nothing, + progress = nothing, + progress_default = nothing, + running = nothing, + cancel = nothing, + cache_args_to_ignore = nothing + ) 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) @@ -138,7 +158,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 ? long_spec : background ) ) end diff --git a/src/app/supporttypes.jl b/src/app/supporttypes.jl index dd913c6..f48a55e 100644 --- a/src/app/supporttypes.jl +++ b/src/app/supporttypes.jl @@ -112,6 +112,8 @@ struct Callback func ::Union{Function, ClientsideFunction} dependencies ::CallbackDeps prevent_initial_call ::Bool + # TODO: refine Any s when done + long ::Any 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..20d1d32 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) @@ -30,7 +35,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 !== false && (interval = callback.long[:interval],) ) end return JSON3.write(result) diff --git a/test/callbacks.jl b/test/callbacks.jl index 2b8f6bd..70952b2 100644 --- a/test/callbacks.jl +++ b/test/callbacks.jl @@ -657,3 +657,22 @@ 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)) + @test deps[1].long.interval == 1000 +end \ No newline at end of file