1

I am trying to execute a longer task (the_longer_function) in the background, and return the response immediately without waiting for the execution of primary function to complete.

Here's the basic code line that I have created:

@app.post("/something/something_test", response_class=JSONResponse)
@validate_token
async def home(request: Request, background_tasks: BackgroundTasks):
    try:
        request_params = await request.json()
        background_tasks.add_task(the_longer_function, request_params)

        return JSONResponse({
            "Result": "Execution Started!"
        }, status_code=200)
    except Exception as ex:
        return {
            "Result": f"Error in starting execution. Error {ex}"
        }

Here's the definition of the_longer_function:

def the_longer_function(request_params):
    variable = None
    try:
        variable = request_params.get('variable', None)
        executionId = str(uuid.uuid4())
        bot_message['ExecutionId'] = executionId
        """
        EXPENSIVE BUSINESS LOGIC HERE
        """
        publish_bot_scan_data(request_params, variable)
    except (JSONDecodeError, Exception) as ex:
        log.error(f"Error {ex}")

I want the API to respond immediately as soon as it adds the task for the new request in the background.

But I have observed, that if the prior request is running, the API is holding the call back and waiting for the previous one to complete and then is returning to the caller.

Have tried, async, trio, parallelism and concurrency but I don't think these are solution to what I am looking for.

Will appreciate the help and input.

Some sources that studied for above:

[https://medium.com/cuddle-ai/concurrency-with-fastapi-1bd809916130](Concurrency-With-FastAPI)

[https://fastapi.tiangolo.com/async/#asynchronous-code](Concurrnecy-and-async/await)

[https://anyio.readthedocs.io/en/stable/](AnyIO)

the.salman.a
  • 945
  • 8
  • 29
  • It does not @Chris, thanks for this link though. – the.salman.a Dec 14 '22 at 07:09
  • I guess this is because `the_longer_function` is not very `async`-friendly, i.e. it blocks the whole time without ever returning execution control back to the async loop (by doing async sleep or waiti, for example). Which means `home` won't run until it's finished. – Jeronimo Dec 14 '22 at 08:14
  • I tried the above using both the options, and then also with async and await, but it doesn't serve the purpose, it still is locking the CPU-bound operation I think as you mentioned @Chris and not moving forward until the previous execution completes itself. – the.salman.a Dec 14 '22 at 11:31
  • Yes @Chris, but I wasn't able to achieve the desired result. Eventually, I had to use `FastAPI`, `RabbitMQ/Redis` and `Celery` to get what I wanted the application to do. – the.salman.a Dec 16 '22 at 04:44

0 Answers0