An I/O event loop. As of Tornado 6.0, `IOLoop` is a wrapper around the `asyncio` event loop. Example usage for a simple TCP server: .. testcode:: import asyncio import errno import functools import socket import tornado from tornado.io
| 70 | |
| 71 | |
| 72 | class IOLoop(Configurable): |
| 73 | """An I/O event loop. |
| 74 | |
| 75 | As of Tornado 6.0, `IOLoop` is a wrapper around the `asyncio` event loop. |
| 76 | |
| 77 | Example usage for a simple TCP server: |
| 78 | |
| 79 | .. testcode:: |
| 80 | |
| 81 | import asyncio |
| 82 | import errno |
| 83 | import functools |
| 84 | import socket |
| 85 | |
| 86 | import tornado |
| 87 | from tornado.iostream import IOStream |
| 88 | |
| 89 | async def handle_connection(connection, address): |
| 90 | stream = IOStream(connection) |
| 91 | message = await stream.read_until_close() |
| 92 | print("message from client:", message.decode().strip()) |
| 93 | |
| 94 | def connection_ready(sock, fd, events): |
| 95 | while True: |
| 96 | try: |
| 97 | connection, address = sock.accept() |
| 98 | except BlockingIOError: |
| 99 | return |
| 100 | connection.setblocking(0) |
| 101 | io_loop = tornado.ioloop.IOLoop.current() |
| 102 | io_loop.spawn_callback(handle_connection, connection, address) |
| 103 | |
| 104 | async def main(): |
| 105 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) |
| 106 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
| 107 | sock.setblocking(0) |
| 108 | sock.bind(("", 8888)) |
| 109 | sock.listen(128) |
| 110 | |
| 111 | io_loop = tornado.ioloop.IOLoop.current() |
| 112 | callback = functools.partial(connection_ready, sock) |
| 113 | io_loop.add_handler(sock.fileno(), callback, io_loop.READ) |
| 114 | await asyncio.Event().wait() |
| 115 | |
| 116 | if __name__ == "__main__": |
| 117 | asyncio.run(main()) |
| 118 | |
| 119 | Most applications should not attempt to construct an `IOLoop` directly, |
| 120 | and instead initialize the `asyncio` event loop and use `IOLoop.current()`. |
| 121 | In some cases, such as in test frameworks when initializing an `IOLoop` |
| 122 | to be run in a secondary thread, it may be appropriate to construct |
| 123 | an `IOLoop` with ``IOLoop(make_current=False)``. |
| 124 | |
| 125 | In general, an `IOLoop` cannot survive a fork or be shared across processes |
| 126 | in any way. When multiple processes are being used, each process should |
| 127 | create its own `IOLoop`, which also implies that any objects which depend on |
| 128 | the `IOLoop` (such as `.AsyncHTTPClient`) must also be created in the child |
| 129 | processes. As a guideline, anything that starts processes (including the |
no outgoing calls