tornado.ioloop — メインイベントループ

ノンブロッキングソケット用の I/O イベントループ。

Tornado 6.0 では、IOLoop は、asyncio イベントループのラッパーであり、インターフェイスが若干異なります。IOLoop インターフェイスは主に下位互換性のために提供されるようになりました。新しいコードでは、一般的に asyncio イベントループインターフェイスを直接使用する必要があります。IOLoop.current クラスメソッドは、実行中の asyncio イベントループに対応する IOLoop インスタンスを提供します。

IOLoop オブジェクト

class tornado.ioloop.IOLoop(*args: Any, **kwargs: Any)[ソース]

I/O イベントループ。

Tornado 6.0 現在、IOLoopasyncio イベントループのラッパーです。

シンプルな TCP サーバーの使い方の例

import asyncio
import errno
import functools
import socket

import tornado
from tornado.iostream import IOStream

async def handle_connection(connection, address):
    stream = IOStream(connection)
    message = await stream.read_until_close()
    print("message from client:", message.decode().strip())

def connection_ready(sock, fd, events):
    while True:
        try:
            connection, address = sock.accept()
        except BlockingIOError:
            return
        connection.setblocking(0)
        io_loop = tornado.ioloop.IOLoop.current()
        io_loop.spawn_callback(handle_connection, connection, address)

async def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.setblocking(0)
    sock.bind(("", 8888))
    sock.listen(128)

    io_loop = tornado.ioloop.IOLoop.current()
    callback = functools.partial(connection_ready, sock)
    io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
    await asyncio.Event().wait()

if __name__ == "__main__":
    asyncio.run(main())

ほとんどのアプリケーションでは、IOLoop を直接構築しようとせず、代わりに asyncio イベントループを初期化し、IOLoop.current() を使用する必要があります。テストフレームワークなど、セカンダリスレッドで実行される IOLoop を初期化する場合など、IOLoop(make_current=False)IOLoop を構築することが適切な場合があります。

一般に、IOLoop はフォークを生き残ったり、プロセス間で共有したりすることはできません。複数のプロセスが使用されている場合、各プロセスは独自の IOLoop を作成する必要があります。これは、IOLoop に依存するオブジェクト(AsyncHTTPClient など)も子プロセスで作成する必要があることを意味します。ガイドラインとして、プロセスを開始するすべてのもの (tornado.process および multiprocessing モジュールを含む) は、できるだけ早く、理想的にはアプリケーションが構成を読み込んだ直後、および IOLoop.start または asyncio.run の呼び出しのに実行する必要があります。

バージョン 4.2 で変更: IOLoop コンストラクタに make_current キーワード引数が追加されました。

バージョン 5.0 で変更: デフォルトで asyncio イベントループを使用します。IOLoop.configure メソッドは、asyncio イベントループを冗長に指定する場合を除き、Python 3 で使用することはできません。

バージョン 6.3 で変更: IOLoop を作成する場合、make_current=True がデフォルトになりました。以前のデフォルトでは、現在のイベントループがまだない場合にイベントループを現在にすることでした。

IOLoop の実行

static IOLoop.current() IOLoop[ソース]
static IOLoop.current(instance: bool = True) Optional[IOLoop]

現在のスレッドの IOLoop を返します。

IOLoop が現在実行中であるか、make_current によって現在としてマークされている場合は、そのインスタンスを返します。現在の IOLoop がなく、instance が true の場合は、インスタンスを作成します。

バージョン 4.1 で変更: IOLoop.instance() へのフォールバックを制御するための instance 引数が追加されました。

バージョン 5.0 で変更: Python 3 では、現在の IOLoop の制御が asyncio に委譲され、このメソッドやその他のメソッドはパススルーアクセサとして使用されます。instance 引数は、IOLoop が存在しない場合に自動的に作成されるかどうかを制御するようになりました。これは IOLoop.instance() にフォールバックするかどうかではなくなりました (これは現在、このメソッドのエイリアスです)。instance=False は非推奨です。たとえ IOLoop を作成しなくても、このメソッドは asyncio ループを初期化する可能性があるためです。

バージョン 6.2 で非推奨化: asyncio イベントループが実行されていないときに IOLoop.current() を呼び出すことは非推奨です。

IOLoop.make_current() None[ソース]

このインスタンスを現在のスレッドの IOLoop にします。

IOLoop は、開始されると自動的にそのスレッドの現在のインスタンスになりますが、開始前に明示的に make_current を呼び出すと、起動時に実行されるコードが正しいインスタンスを見つけることができるため、便利な場合があります。

バージョン 4.1 で変更: 現在の IOLoop が存在しない状態で作成された IOLoop は、自動的に現在のインスタンスになります。

バージョン 5.0 で変更: このメソッドは、現在の asyncio イベントループも設定します。

バージョン 6.2 で非推奨化: Tornado を介して現在のイベントループを設定およびクリアすることは非推奨です。これが必要な場合は、代わりに asyncio.set_event_loop を使用してください。

static IOLoop.clear_current() None[ソース]

現在のスレッドの IOLoop をクリアします。

主にテストフレームワークがテストの間で使用することを想定しています。

バージョン 5.0 で変更: このメソッドは、現在の asyncio イベントループもクリアします。

バージョン 6.2 から非推奨となりました。

IOLoop.start() None[ソース]

I/O ループを開始します。

ループは、いずれかのコールバックが stop() を呼び出すまで実行されます。これにより、現在のイベントイテレーションが完了した後でループが停止します。

IOLoop.stop() None[ソース]

I/O ループを停止します。

イベントループが現在実行されていない場合、start() の次の呼び出しはすぐに戻ります。

stop が呼び出された後でも、IOLoop は、IOLoop.start も戻るまで完全に停止しません。stop の呼び出し前にスケジュールされた一部の処理は、IOLoop がシャットダウンする前に実行される可能性があります。

IOLoop.run_sync(func: Callable, timeout: Optional[float] = None) Any[ソース]

IOLoop を開始し、指定された関数を実行し、ループを停止します。

関数は、awaitable オブジェクトまたは None のいずれかを返す必要があります。関数が awaitable オブジェクトを返す場合、IOLoop は awaitable が解決されるまで実行されます (そして run_sync() は awaitable の結果を返します)。例外が発生した場合、IOLoop は停止し、例外は呼び出し元に再発生します。

キーワード専用引数 timeout を使用して、関数の最大継続時間を設定できます。タイムアウトが期限切れになった場合は、asyncio.TimeoutError が発生します。

このメソッドは、main() 関数で非同期呼び出しを許可するために役立ちます。

async def main():
    # do stuff...

if __name__ == '__main__':
    IOLoop.current().run_sync(main)

バージョン 4.3 で変更: None でも awaitable 値でもない値を返すことは、エラーになりました。

バージョン 5.0 で変更: タイムアウトが発生した場合、func コルーチンはキャンセルされます。

バージョン 6.2 で変更: tornado.util.TimeoutError は、asyncio.TimeoutError のエイリアスになりました。

IOLoop.close(all_fds: bool = False) None[ソース]

IOLoop を閉じ、使用されているリソースを解放します。

all_fds が true の場合、IOLoop に登録されているすべてのファイル記述子 ( IOLoop 自体が作成したものだけでなく) が閉じられます。

多くのアプリケーションは、プロセス全体で実行される単一の IOLoop のみを使用します。その場合、プロセスが終了するときにすべてがクリーンアップされるため、IOLoop を閉じる必要はありません。IOLoop.close は、主に、多数の IOLoops を作成および破棄する単体テストなどのシナリオ向けに提供されています。

IOLoop.update_handler(fd: Union[int, _Selectable], events: int) None[ソース]

fd に対して監視するイベントを変更します。

IOLoop.remove_handler(fd: Union[int, _Selectable]) None[ソース]

fd でのイベントの監視を停止します。

コールバックとタイムアウト

IOLoop.add_callback(callback: Callable, *args: Any, **kwargs: Any) None[ソース]

次の I/O ループのイテレーションで、指定されたコールバックを呼び出します。

シグナルハンドラを除く、任意の時点、任意のスレッドからこのメソッドを呼び出すのは安全です。これは、IOLoop でこのスレッドセーフ性を保証する唯一のメソッドであることに注意してください。IOLoop との他のすべてのやり取りは、その IOLoop のスレッドから行う必要があります。add_callback() を使用して、他のスレッドから IOLoop のスレッドに制御を移すことができます。

IOLoop.add_callback_from_signal(callback: Callable, *args: Any, **kwargs: Any) None[ソース]

次の I/O ループのイテレーションで、指定されたコールバックを呼び出します。

Python のシグナルハンドラからの使用を想定しており、それ以外の場合は使用しないでください。

バージョン 6.4 で非推奨化: 代わりに asyncio.AbstractEventLoop.add_signal_handler を使用してください。このメソッドは Tornado 5.0 から破損している疑いがあり、バージョン 7.0 で削除されます。

IOLoop.add_future(future: Union[Future[_T], concurrent.futures.Future[_T]], callback: Callable[[Future[_T]], None]) None[ソース]

指定された Future が完了したときに、IOLoop でコールバックをスケジュールします。

コールバックは、Future を1つの引数として呼び出されます。

このメソッドは、(Tornado のほとんどの場合とは異なり、2つを相互に交換可能とする) Future オブジェクトのみを受け入れます。

IOLoop.add_timeout(deadline: Union[float, timedelta], callback: Callable, *args: Any, **kwargs: Any) object[ソース]

I/O ループから deadline 時刻に callback を実行します。

キャンセルするために remove_timeout に渡すことができる不透明なハンドルを返します。

deadline は、時間を示す数値 ( IOLoop.time と同じスケールで、通常は time.time )、または現在時刻からの相対的な期限を表す datetime.timedelta オブジェクトである場合があります。Tornado 4.0 以降、相対的な場合、timedelta オブジェクトを必要としないため、call_later がより便利な代替手段です。

別のスレッドから add_timeout を呼び出すのは安全ではないことに注意してください。代わりに、add_callback を使用して IOLoop のスレッドに制御を移し、そこから add_timeout を呼び出す必要があります。

IOLoop のサブクラスは、add_timeout または call_at のいずれかを実装する必要があります。それぞれのデフォルトの実装はもう一方を呼び出します。call_at は通常実装がより簡単ですが、Tornado 4.0 より前のバージョンとの互換性を維持したいサブクラスは、代わりに add_timeout を使用する必要があります。

バージョン 4.0 で変更: コールバックに *args**kwargs を渡すようになりました。

IOLoop.call_at(when: float, callback: Callable, *args: Any, **kwargs: Any) object[ソース]

when で指定された絶対時刻に callback を実行します。

whenIOLoop.time と同じ基準点を使用する数値である必要があります。

キャンセルするために remove_timeout に渡すことができる不透明なハンドルを返します。同じ名前の asyncio メソッドとは異なり、返されるオブジェクトには cancel() メソッドがないことに注意してください。

スレッドセーフとサブクラス化に関するコメントについては、add_timeout を参照してください。

バージョン 4.0 で新規追加。

IOLoop.call_later(delay: float, callback: Callable, *args: Any, **kwargs: Any) object[ソース]

delay 秒経過後に callback を実行します。

キャンセルするために remove_timeout に渡すことができる不透明なハンドルを返します。同じ名前の asyncio メソッドとは異なり、返されるオブジェクトには cancel() メソッドがないことに注意してください。

スレッドセーフとサブクラス化に関するコメントについては、add_timeout を参照してください。

バージョン 4.0 で新規追加。

IOLoop.remove_timeout(timeout: object) None[ソース]

保留中のタイムアウトをキャンセルします。

引数は add_timeout によって返されるハンドルです。コールバックがすでに実行されている場合でも、remove_timeout を呼び出すのは安全です。

IOLoop.spawn_callback(callback: Callable, *args: Any, **kwargs: Any) None[ソース]

次の IOLoop イテレーションで、指定されたコールバックを呼び出します。

Tornado 6.0 の時点では、このメソッドは add_callback と同等です。

バージョン 4.0 で新規追加。

IOLoop.run_in_executor(executor: Optional[Executor], func: Callable[[...], _T], *args: Any) Future[_T][ソース]

concurrent.futures.Executor で関数を実行します。executorNone の場合、IO ループのデフォルトの executor が使用されます。

func にキーワード引数を渡すには、functools.partial を使用してください。

バージョン 5.0 で新規追加。

IOLoop.set_default_executor(executor: Executor) None[ソース]

run_in_executor() で使用するデフォルトのエグゼキューターを設定します。

バージョン 5.0 で新規追加。

IOLoop.time() float[ソース]

IOLoop のクロックに従って現在の時間を返します。

戻り値は、過去の不特定時点からの相対的な浮動小数点数です。

歴史的に、IOLoop は、例えば time.time の代わりに time.monotonic を使用するようにカスタマイズできましたが、現在これはサポートされておらず、このメソッドは time.time と同等です。

class tornado.ioloop.PeriodicCallback(callback: Callable[[], Optional[Awaitable]], callback_time: Union[timedelta, float], jitter: float = 0)[ソース]

指定されたコールバックを定期的に呼び出すようにスケジュールします。

callback_time が float の場合、コールバックは callback_time ミリ秒ごとに呼び出されます。タイムアウトはミリ秒単位で指定されることに注意してください。Tornado の他のほとんどの時間関連関数は秒を使用します。callback_time は、datetime.timedelta オブジェクトとして指定することもできます。

jitter が指定されている場合、各コールバック時間は、jitter * callback_time ミリ秒の範囲内でランダムに選択されます。ジッターは、同様の期間を持つイベントのアライメントを減らすために使用できます。0.1 のジッターは、コールバック時間の 10% の変動を許可することを意味します。ウィンドウは callback_time を中心に配置されるため、特定の時間間隔内の呼び出しの合計数は、ジッターを追加しても大幅に影響を受けることはありません。

コールバックの実行時間が callback_time ミリ秒よりも長い場合、スケジュールに戻るために後続の呼び出しはスキップされます。

start は、PeriodicCallback が作成された後に呼び出す必要があります。

バージョン 5.0 で変更: io_loop 引数(バージョン 4.1 から非推奨)が削除されました。

バージョン 5.1 で変更: jitter 引数が追加されました。

バージョン 6.2 で変更: callback 引数がコルーチンの場合、コールバックの実行時間が callback_time より長い場合、後続の呼び出しはスキップされます。以前は、これは通常の関数にのみ当てはまり、PeriodicCallback では「fire-and-forget」であったコルーチンには当てはまりませんでした。

callback_time 引数は、以前の数値ミリ秒に加えて、datetime.timedelta オブジェクトを受け入れるようになりました。

start() None[ソース]

タイマーを開始します。

stop() None[ソース]

タイマーを停止します。

is_running() bool[ソース]

この PeriodicCallback が開始されている場合は True を返します。

バージョン 4.1 で新規追加.