try:
instance.createandwritelocaldb((stringonecol, ))
except Exception as error:
print('Error writing DWDS to db!', error)
...
await asyncwrite2sqliteonecol(instance, stringonecol)
asyncio.get_event_loop().create_task() is a lower-level asyncio function that schedules a coroutine to be run on the event loop. It's a general-purpose way to run tasks concurrently in any asyncio-based application.
app.add_background_task() is a Quart-specific method that adds a task to be run in the background when the Quart app is running. One key feature of app.add_background_task() is that it ensures the task finishes during the shutdown of the Quart app, unless the server times out and cancels it. This is particularly useful in a production environment where you want to ensure that all tasks are completed before the app shuts down.
In terms of performance, there should not be a significant difference between the two methods. Both methods will run the tasks concurrently, which can lead to a significant performance improvement over running the tasks sequentially, especially for IO-bound tasks.
However, if you're writing to multiple SQLite databases, you should be aware that SQLite is not designed for high-level concurrency. It uses a file-based locking system for transactions which can become a bottleneck when many tasks are writing to the database concurrently. If high-level concurrency is required, you might want to consider using a different database system that is designed for concurrent access, such as PostgreSQL or MySQL.
The reason is that app.add_background_task is designed to ensure that the tasks finish during the shutdown of the application (unless the server times out and cancels). This is particularly useful in a production environment where you'd want all tasks to complete before the application shuts down.
On the other hand, asyncio.get_event_loop().create_task does not provide this guarantee. If the application shuts down before the task completes, the task may be cancelled and not finish its work. So, for writing to a database, which is a critical operation that should not be interrupted, app.add_background_task would be a better choice.
*******
functools.partial
is a function in Python's standard library that allows you to fix a
certain number of arguments of a function and generate a new function.
This can be useful when you want to "freeze" some parameters of a
function.
Here is a simple example:
from functools import partial def multiply(x, y): return x * y # Create a new function that multiplies by 2 double = partial(multiply, 2) print(double(4)) # Outputs: 8
In the context of the Quart code you've been working with, functools.partial
could be used in scenarios where you want to predefine some arguments of a function that you want to run as a background task. For instance, if you have a function that writes to a
SQLite database and takes the database connection and some data as
arguments, you could use
functools.partial
to create a new function that has the database connection already set:
In this example,from functools import partial def write_to_db(connection, data): # Code to write data to the database # Create a new function that writes to a specific database write_to_specific_db = partial(write_to_db, specific_connection) # Now you can use write_to_specific_db in your code and only pass the data app.add_background_task(write_to_specific_db, data)
write_to_specific_db
is a new function that takes only one argument (data
), and uses specific_connection
as the database connection. Source: AI from https://www.getonboard.dev****
Quart has startup and shutdown methods that allow something to be started before the server starts serving and stopped when the server finishes serving. If your background task is mostly IO bound I'd recommend just using a coroutine function rather than a thread,
async def background_task():
while True:
...
@app.before_serving
async def startup():
app.background_task = asyncio.ensure_future(background_task())
@app.after_serving
async def shutdown():
app.background_task.cancel() # Or use a variable in the while loop
Or you can do the same with your Service,
@app.before_serving
async def startup():
service.start()
@app.after_serving
async def shutdown():
service.stop()
Note to check:
app.add_background_task(background_task) in "before" and app.background_tasks.pop().cancel() in "after".
https://stackoverflow.com