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 現在、
IOLoopはasyncioイベントループのラッパーです。シンプルな 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を呼び出すと、起動時に実行されるコードが正しいインスタンスを見つけることができるため、便利な場合があります。バージョン 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.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を実行します。whenはIOLoop.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で関数を実行します。executorがNoneの場合、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オブジェクトを受け入れるようになりました。- is_running() bool[ソース]¶
この
PeriodicCallbackが開始されている場合はTrueを返します。バージョン 4.1 で新規追加.