I have an Agents.jl simulation that worked fine last summer… I’m back to looking at the code, and it’s deadlocking and sitting there using 0% of cpu.
It’s a script that uses Threads.@spawn to run some threads each of which reads a simulation description from a channel, runs the simulation, and then put! some summary statistics to a statistics channel. In a separate single thread a function reads from the stats channel and writes stats to a SQLite database.
As I said, all of this worked fine last summer on some version like 1.5.2 or something along those lines. Today in 1.7.0-beta3 (or beta2) it gets to the point where the worker threads have each read a simulation description (and print out what it is) and where the SQLite writer says it’s about to grab the next DB result… but at that point, everything deadlocks and 0% CPU usage.
It doesn’t appear that the ABM runs at all. Here is the code the threads are running. One thread is spawned to run
sqliteinserter, and 5 threads are spawned to run
function sqliteinserter(dfchannel,dbfile) db = SQLite.DB(dbfile); SQLite.drop!(db,"sims";ifexists=true) SQLite.drop!(db,"stats";ifexists=true) SQLite.createtable!(db,"sims",Tables.Schema((:simid,:n,:density,:infprob,:testevery,:poolsize, :quarduration,:costoftest,:limitdet), (Int,Int,Float64,Float64,Int,Int,Int,Float64,Float64))); SQLite.createtable!(db,"stats",Tables.Schema((:simid,:day,:ninfected,:nquarantined,:tottestcost), (Int,Int,Int,Int,Float64))); while true println("about to grab next results for DB.") tup = take!(dfchannel) if tup === nothing return end iter,adf,mdf,pars = tup; println("Completed iteration $iter, adding to SQLite database"); cmd = "insert into sims values(" * Printf.@sprintf("%d,%d,%f,%f,%d,%d,%d,%f,%f);",pars...) DBInterface.execute(db,cmd); DBInterface.execute(db,"drop table if exists tempstats;") SQLite.load!(mdf,db,"tempstats",temp=true,ifnotexists=true) DBInterface.execute(db,"insert into stats select $iter,day,ninfected,nquarantined,tottestcost from tempstats;") end end function runasim(simchannel,dfchannel) while true tup = take!(simchannel) println("Got new sim $tup") if tup === nothing println("Done with thread $(Threads.threadid())") return end iter,sim = tup; testmodel = covid_model(;sim...) println("About to run model!") adf,mdf = run!(testmodel,step_covperson!,stepcovmodel!,365; adata=,mdata=[:day,:ninfected,:nquarantined,:tottestcost]) println("Finished sim $tup") put!(dfchannel,(iter,adf,mdf,(simid=iter,sim...))) end end
I see printed messages like:
Got new sim (1, (n = 10000, density = 7.957747154594767, infprob = 0.008, testevery = 14, poolsize = 1, quarduration = 14, costoftest = 120.0, limitdet = 1000.0))
but I never see
About to run model!
So at some point after it takes the message from its channel, and before it gets to the println for that message… everything halts.
I’m pretty sure that’s not me doing something stupid, and the tasks aren’t printing the exit message. I don’t think I’m doing anything wrong here, so it feels like there’s a bug. Also it all worked a year ago.