Does a Background Task keep its anvil.server.session
alive? Or are the two objects’ lifetimes completely independent?
A background task runs in its own session, separate from the session that launched it. If you want to communicate with it, use the anvil.server.task_state
variable, which can be read from outside the task by calling get_state()
on the task object returned by anvil.server.launch_background_task()
.
Thanks, @meredydd. Hmmm… Related guesswork (please check me on these):
- The Task’s code has no access to any
anvil.server.session
. Instead, it should use only its ownanvil.server.task_state
. - A Task’s own
anvil.server.task_state
is read/write within its Task, and read-only everywhere else, including in the code of other Tasks. - Constraints on the contents of
anvil.server.task_state
are identical to those ofanvil.server.session
. - If the Task needs access to information from
anvil.server.session
, then it is the caller’s responsibility to furnish it, via additional parameters toanvil.server.launch_background_task()
. -
anvil.server.session
should not be one of those parameters. (Rationale:anvil.server.session
is not an actual dict, just a proxy for more durable storage. Unlike a conventional dict, we can’t “just make it live longer” by binding it to an entry withinanvil.server.task_state
.) - There is probably some way a Task can make itself sleep (give up its CPU time to other Tasks, e.g., when it is waiting for some external event).
-
A running background task does have a session (you can set
anvil.server.session
, you can log in with the Users service, etc); it’s just isolated from everything else. -
Correct.
-
Correct.
-
Yes, you supply data when you launch a task. That data is also subject to the same restrictions as an
anvil.server.call()
. -
Yeah; the
anvil.server.session
object is not serialisable. Think of a background task like a function call - pass only the arguments you need to pass. -
Not really. (I mean, you can
time.sleep()
if you like, but we will still count that against your CPU quota). If you’re waiting for some event to do the next step in a process, you should do that next step (or launch a background task to do it) when the event occurs.
(Thank-you, by the way, for the questions! We’re going to make sure that our reference docs clearly answer them all.)
This is great! Thanks so much!
- A Task can keep “private” data in its
anvil.server.session
, and data for “public” consumption in itsanvil.server.task_state
. - Tasks shouldn’t sleep, in order to accomplish multiple condition-driven stages. Instead, each stage should be broken out into its own Task, and triggered by some kind of event.
- How do we know which stage we’re in? This information must persist between tasks, e.g., as a value in a database row…
What about using time.sleep()
on a dedicated server?
(I agree, it is usually better to split a task in different chunks and run each when it’s time to run it. But sometimes (especially considering the absence of a scheduler) it’s just simpler to put a task to sleep.)
Dedicated server users don’t have CPU limits