Background tasks are a lightweight mechanism to perform processing after a request has been sent, without making the client wait for the result. Typical examples include sending email, or sending logs to a remote system.
How do background tasks work?
When registered on the Response, the background task won't run immediately. Instead, the view will terminate as usual, and the response will be sent. Only then, the background task will execute.
This prevents clients from waiting for the background task to finish before getting a response.
In the meantime, the server will still be able to process other requests while the background task executes — provided the task is non-blocking (see Caveats).
Creating a background task
To create a background task, decorate a no-argument async function with
@res.background inside a view.
Here's an example that simulates sending a confirmation email:
from asyncio import sleep from bocadillo import App, view app = App() @app.route("/orders", methods=["post"]) async def create_order(req, res): @res.background def send_confirmation(): # TODO: send an email here await sleep(1) res.status_code = 201
You can also use
res.background() as a regular function: extra arguments or keyword arguments will be passed to the task function. This is useful to define reusable parametrized tasks.
from asyncio import sleep from bocadillo import App, view app = App() async def send_confirmation(who: str): # TODO: send an email here await sleep(1) @app.route("/orders", methods=["post"]) async def create_order(req, res): res.background(send_confirmation, who="firstname.lastname@example.org") res.status_code = 201
- Background tasks must be non-blocking.
Because a background task is a coroutine, it must be non-blocking to avoid blocking the main thread and preventing requests from being processed.
If you're unable to write an async-native background tasks, use one of the techniques described in Executing CPU-bound operations.
- Multiple background tasks aren't supported.
Only the latest task registered via
@res.background will execute — previous ones are simply ignored.
If you need to perform multiple things concurrently (e.g. send multiple emails), you should resort to