Run synchronous code¶
Synchronous code will block the event loop and degrade the performance of the Quart application it is run in. This is because the synchronous code will block the task it is run in and in addition block the event loop. It is for this reason that synchronous code is best avoided, with asynchronous versions used in preference.
It is likely though that you will need to use a third party library that is synchronous as there is no asynchronous version to use in its place. In this situation it is common to run the synchronous code in a thread pool executor so that it doesn’t block the event loop and hence degrade the performance of the Quart application. This can be a bit tricky to do, so Quart provides some helpers to do so. Firstly any synchronous route will be run in an executor, i.e.
@app.route("/") def sync(): method = request.method ...
will result in the sync function being run in a thread. Note that you
are still within the Contexts, and hence you can still access
current_app and other globals.
The following functionality accepts synchronous functions and will run them in a thread,
Before first request
Teardown app context
Make null session
Whilst you can access the
request and other globals in synchronous
routes you will be unable to await coroutine functions. To work around
this Quart provides
run_sync() which can be
used as so,
@app.route("/") async def sync_within(): data = await request.get_json() def sync_processor(): # does something with data ... result = await run_sync(sync_processor)() return result
this is similar to utilising the asyncio run_in_executor function,
@app.route("/") async def sync_within(): data = await request.get_json() def sync_processor(): # does something with data ... result = await asyncio.get_running_loop().run_in_executor( None, sync_processor ) return result
The run_in_executor function does not copy the current context,
whereas the run_sync method does. It is for this reason that the
latter is recommended. Without the copied context the
and other globals will not be accessible.