# バックグラウンドタスク

# Tasksを作成

非同期Pythonでtasks (opens new window)を使用することは、望ましいことが多く、非常に便利です。Sanicは、現在実行中の**ループにタスクを追加する便利な方法を提供します。これはasyncio.create_task。'App'ループの実行前にタスクを追加する方法については、次のセクションを参照してください。

async def notify_server_started_after_five_seconds():
    await asyncio.sleep(5)
    print('Server successfully started!')
app.add_task(notify_server_started_after_five_seconds())

Sanicは自動的にアプリを注入し、タスクへの引数として渡す。

async def auto_inject(app):
    await asyncio.sleep(5)
    print(app.name)
app.add_task(auto_inject)

または、app引数を明示的に渡すこともできます。

async def explicit_inject(app):
    await asyncio.sleep(5)
    print(app.name)
app.add_task(explicit_inject(app))

# app.runの前にタスクを追加します

Appを実行する前にバックグラウンドタスクを追加することができます。app.runの前に置きます。Appが実行される前にタスクを追加するには、コルーチンオブジェクト(つまり、。asynccallable)を渡さずに、単に呼び出し可能オブジェクトを渡すことをお勧めします。Sanicは各ワーカーにコルーチンオブジェクトを作成します**.注:追加されるタスクはbefore_server_startジョブとして実行されるため、すべてのワーカーで実行されます (メインプロセスでは実行されません) 。これには特定の結果が伴います。詳細については、この問題 (opens new window)このコメント (opens new window) を参照してください。

メイン・プロセスに作業を追加するには、@app.main_process_start。注意:この作業が完了するまで、就業者は開始しません。

app.runの前にタスクを追加する例

async def slow_work(...):
   ...
app = Sanic(...)
app.add_task(slow_work) # Note: we are passing the callable and not coroutine object `slow_work(...)`
app.run(...)

TIP

上記のslow_workにパラメータを渡すには、functools.partialを使用します。

# Named tasks

NEW in v21.12

Python 3.8以上でのみサポートされます

タスクを作成するときに、nameを指定することで、Sanicにそのタスクを追跡するように依頼することができます。

app.add_task(slow_work, name="slow_task")

これで、アプリケーションのどこからでも get_task を使って、そのタスクのインスタンスを取得できるようになりました。

task = app.get_task("slow_task")

そのタスクをキャンセルする必要がある場合は、 cancel_task を使って行うことができます。必ず await してください。

await app.cancel_task("slow_task")

登録されたすべてのタスクは app.tasks プロパティで確認することができます。キャンセルされたタスクが一杯になるのを防ぐために、app.purge_tasksを実行して、完了したタスクやキャンセルされたタスクを消去するとよいでしょう。

app.purge_tasks()

このパターンは、特に websocket で有効です:

async def receiver(ws):
    while True:
        message = await ws.recv()
        if not message:
            break
        print(f"Received: {message}")
@app.websocket("/feed")
async def feed(request, ws):
    task_name = f"receiver:{request.id}"
    request.app.add_task(receiver(ws), name=task_name)
    try:
        while True:
            await request.app.event("my.custom.event")
            await ws.send("A message")
    finally:
        # When the websocket closes, let's cleanup the task
        await request.app.cancel_task(task_name)
        request.app.purge_tasks()
MIT Licensed
Copyright © 2018-present Sanic Community Organization

~ Made with ❤️ and ☕️ ~