Wait for background task to complete?

What I’m trying to do:
I want to use background-task functions in my server code to pull information from multiple API’s since doing it otherwise takes too long between the different calls.

What I’ve tried and what’s not working:
I check if task.is_completed() and execute the rest of the code if it is. I noticed that the code that is supposed to be run on is_completed wasn’t running so I put a print statement in it and checked the app logs to see the print but saw that the entire chunk just wasn’t executing. I wasn’t sure if the compiler was just skipping over the entire section before the tasks finished or something similar but I’m not too strong with this Anvil feature.

Code Sample:

# Fires upon receiving a webhook
@anvil.server.http_endpoint('/grab', methods = ['POST'])
def buildThing():
   body = anvil.server.request.body_json
   bg = anvil.server.launch_background_task("getDetails", body, datetime.today())
   if bg.is_completed():
      values = bg.get_return_value()
      print(values) #check
      #other stuff that wasn't firing


@anvil.server.background_task
def getDetails(body, date):
   data = requests.post(
      "sample.url.com/data",
      json = {"authtoken": token}
   )
   
   people = requests.post(
      "sample.url.com/people",
       json = {"authtoken": token,
                    "date": date}
   ) 

   places = requests.post(
      "sample.url.com/places",
      json = {"authtoken": token}
   )
  # Wrangle JSON to get desired values
  return(desiredValue1, desiredValue2, desiredValue3)  

This looks like you’re checking if the task was complete immediately after creating the task. This will certainly return false.

You can set up a while loop to check if the task is complete, but that will hang up any caller waiting for a response from your api. If you’re using this on the client side, I often set up a time to check the status on task, on a routine.

discussion of that touches the subject here:

1 Like

Gotcha. I wasn’t sure how to approach this since I’m essentially just trying to asynchronously access API’s while the main program does the rest of what’s needed, and once it’s done then the main program can just grab the necessary values like a sort of coroutine since those API calls aren’t immediately necessary and can take a bit between Anvil’s server spin-up time and the requests.

I wasn’t sure if async and await was doable in Anvil either so I opted for what was documented.

1 Like

I haven’t used either in the scope of anvil, but I’m sure someone has discussed it on the forum.

I would look into Running Tasks in the Background, in this tutorial they set up a timer to communicate with background task. It shouldn’t hold up your UI either.

1 Like

Appreciate the lead! I’ll see what I can do in the meantime while waiting to see if other’s have any insights, since my “app” isn’t really an application to be used by anyone. It’s just a blank client whose main functionality is to just be hosted and listen for a webhook that regularly gets triggered. Then the server code wrangles everything and passes it on to the next step in my workflow.

1 Like

You can use scheduled tasks to periodically run a server function. That scheduled task can check the status of the background task, taking the same role as the timer on a form would in a user facing app.

1 Like

This may be useful: How to clear the list of background tasks? - #3 by stefano.menci

1 Like

Thanks so much for the insight on how to work around this! Do you mind sharing your implementation details? Just so I can get an idea of how the steps intermingle.

Thank you so much for the suggestion! I’ll play around with scheduled tasks to see if it can fit my needs.

In the meantime though, just at a cursory glance, would this sort of implementation work if the asynchronous functions I use rely on data that’s received when the overall app receives the webhook it’s listening for?

Like some event handler for when a webhook is received?

The real thing is more complex than it needs to be, because of some details of my configuration.

The generic description is here: How long do background tasks stay in the list? - #6 by stefano.menci

Let me know if you need more details.

1 Like

That’s definitely enough details for me. Much appreciated!

Yes, if you pass data to the background task from the webhook, the background task can do its job and then return data to the scheduled task.

Although, at that point, with your setup, I’m not sure why you wouldn’t just have the background task do what’s needed at the end (e.g. insert into a data table, ping some other webhook, etc). The scheduled task probably isn’t gaining you anything.

2 Likes

Thank you so much for the rough estimate/take. One final question I have is if I can use multiple decorators in Anvil?

I think all Anvil decorators work together without problems.

In some cases the order the decorators are applied counts, but I don’t remember when. When this is the case it is mentioned in the documentation.

4 Likes

@stefano.menci and @jshaffstall you guys rock! Thank you so much!

1 Like