Stipple.jl
Stipple.jl copied to clipboard
Calling @onchange while a @task is running causes "Failed to store session data" error
I have a variable total that each second is increased by an amount x taken from a text field in the UI. This is done asynchronously with a @task so that the program can listen to @onchange events.
using GenieFramework
@genietools
@handlers begin
p = @task 1+1
total = 0
@in x = 0.00
@onchange x begin
if !istaskstarted(p) || istaskdone(p)
p = @task begin
println("Task started")
while total <= 100
total = total + x
println(total)
sleep(1)
end
end
schedule(p)
end
end
end
function ui()
textfield("x value", :x)
end
@page("/", ui)
Server.isrunning() || Server.up()
It works, but when I change the value of x from 1 to 2 I get the following:
Task started
1.0
2.0
3.0
4.0 <---- Here I change x to 2
┌ Error: 2023-01-17 17:03:27 Failed to store session data
└ @ GenieSessionFileSession ~/.julia/packages/GenieSessionFileSession/otnJC/src/GenieSessionFileSession.jl:41
6.0┌ Error: 2023-01-17 17:03:27 ErrorException("cannot serialize a running Task")
└ @ GenieSessionFileSession ~/.julia/packages/GenieSessionFileSession/otnJC/src/GenieSessionFileSession.jl:42
┌ Error: 2023-01-17 17:03:27 Resetting session
└ @ GenieSessionFileSession ~/.julia/packages/GenieSessionFileSession/otnJC/src/GenieSessionFileSession.jl:46
8.0
10.0
12.0
I've also tried defining the task outside of the @onchange block, but in that case the counter does not increase.
@handlers begin
p = @task 1+1
total = 0
@in x = 0.00
p = @task begin
println("Task started")
while total <= 100
total = total + x
println(total)
sleep(1)
end
end
@onchange x begin
if !istaskstarted(p) || istaskdone(p)
schedule(p)
end
end
end
What is the cause of this error? Can it be fixed somehow?
For a little more context, here's what I'm trying to do. I want to have a differential equation simulation running in the background, and control the eq's parameters in the UI. The simulation is run by calling a solver function in a loop over time. Whenever a parameter is changed, the diff eq should be instantly updated and the simulation proceed with the new parameters.
In the code below, the step! function in the while loop calculates the eq solution at t+t_step. The value of t_step can be set from the UI. This works well, only I'm getting the error in the previous post.
using GenieFramework
using DifferentialEquations, ModelingToolkit
@genietools
function define_ODE()
@parameters t σ ρ β
@variables x(t) y(t) z(t)
D = Differential(t)
eqs = [D(x) ~ σ * (y - x),
D(y) ~ x * (ρ - z) - y,
D(z) ~ x * y - β * z]
@named sys = ODESystem(eqs)
sys = structural_simplify(sys)
u0 = [x => 1.0,
y => 0.0,
z => 0.0]
p = [σ => 10.0,
ρ => 28.0,
β => 8 / 3]
tspan = (0.0, 100.0)
ODEProblem(sys, u0, tspan, p, jac = true)
end
prob = define_ODE()
integrator = DifferentialEquations.init(prob, Tsit5())
t_end=100
@handlers begin
p = @task 1+1
schedule(p)
prob = define_ODE()
@in t_step = 0.00
@onchange t_step begin
println(t_step)
if p._state == 1
p = @task begin
@show p._state
while integrator.sol.t[end] <= t_end
sleep(1)
println(integrator.sol.t[end],' ', t_step, ' ', p._state)
step!(integrator, t_step)
end
DifferentialEquations.reinit!(integrator)
end
schedule(p)
end
end
end
function ui()
textfield("Time step", :t_step)
end
@page("/", ui)
Server.isrunning() || Server.up()