What I’m trying to do:
Get the running background tasks.
What I’ve tried and what’s not working:
anvil.server.list_background_tasks() gives me some old tasks, completed and not running anymore.
I am looking the list my last running background tasks.
Code Sample:
for task in anvil.server.list_background_tasks():
if task.is_running():
print("Active task : " + task.get_task_name())
returns nothing, though I can see a running background task in Anvil logs.
Is there any option or parameter?
Thanks for your help.
Were the background tasks started in the editor? Running the above in the editor would show a different environment than what would be shown if the task had been started from a production environment.
If you want to see all tasks in all environments then try: anvil.server.list_background_tasks(all_environments=True)
Many thanks I missed that one.
Unfortunately, result is the same.
Here a screenshot of my latest background tasks (today, means the latest was launched on the 19th and is still running) :
Save your background task ID somwhere where you can access it and then use it to search for the right task OR change the code to filter just for tasks that are running skipping the ID part
@anvil.server.callable
def get_existing_tasks(task_id):
"""track active tasks"""
if task_id is not None:
return [
t for t in anvil.server.list_background_tasks() if t.get_id() == task_id and t.get_termination_status() != 'failed' or 'completed'
]
Great, thank you.
Yes, this might be the wrong way to parse all background tasks, even the old ones. I don’t care about the old tasks that have failed, and this approach will make the processing even heavier. I will store task IDs and manage my background tasks accordingly.
Also, I don’t know if it has become better since I was heavily coding background tasks, but the task.is_completed() and task.is_running() methods for a task object is/was/are not very reliable and buggy.
The workaround for almost everyone is having the task at least return some object (…even just True or False) other than just a None object.
Then calling task.get_return_value() and evaluating it with:
task.get_return_value() is not None
This seems to be the only 100% reliable way to know if a task is running/completed or not programmatically.
Depends on your aim. He wanted to get all running tasks or track multiple tasks.
To track a single task, that is running and you want to wait for it, then timer component + something like this:
def start_action(self)
#start the task
self.task = anvil.server.call('server_func', var1, var2) #return task from the initiated background task
self.timer_1.interval = 1#set timer
Maybe progress is something new, but it let you to send some simple data that you can already use while it is running or just a number that indicates how much in % is already completed.
def timer_1_tick(self, **event_args):
"""This method is called Every [interval] seconds. Does not trigger if [interval] is 0."""
with anvil.server.no_loading_indicator:
# Show progress
state = self.task.get_state()
if self.task.is_running():
progress = state.get('progress', 0)
#some component to indicate progress
self.horizontal_progressbar_component_1.value = int(progress)
else:
#for example retrieve some data
self.id_export = self.task.get_return_value()
Maybe it works better now, or maybe you have found an even better workaround by calling task.get_state() first, it might be making a round trip to the server and updating the task object better than the direct evaluation + call of just if task.is_running():
Either way, this is a much better solution to get the task methods to operate “as advertised” the way it says it works in the docs.