An I/O event loop for non-blocking sockets.
On Python 3, IOLoop
is a wrapper around the asyncio
event loop.
Typical applications will use a single IOLoop
object, accessed via
IOLoop.current
class method. The IOLoop.start
method (or
equivalently, asyncio.AbstractEventLoop.run_forever
) should usually
be called at the end of the main()
function. Atypical applications
may use more than one IOLoop
, such as one IOLoop
per thread, or
per unittest
case.
In addition to I/O events, the IOLoop
can also schedule time-based
events. IOLoop.add_timeout
is a non-blocking alternative to
time.sleep
.
IOLoop objects
class tornado.ioloop.IOLoop[source]
A level-triggered I/O loop.
On Python 3, IOLoop
is a wrapper around the asyncio
event
loop. On Python 2, it uses epoll
(Linux) or kqueue
(BSD
and Mac OS X) if they are available, or else we fall back on
select(). If you are implementing a system that needs to handle
thousands of simultaneous connections, you should use a system
that supports either epoll
or kqueue
.
Example usage for a simple TCP server:
import errno
import functools
import socket
import tornado.ioloop
from tornado import gen
from tornado.iostream import IOStream
@gen.coroutine
def handle_connection(connection, address):
stream = IOStream(connection)
message = yield 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 socket.error as e:
if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
raise
return
connection.setblocking(0)
handle_connection(connection, address)
if __name__ == '__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)
io_loop.start()
By default, a newly-constructed IOLoop
becomes the thread’s current
IOLoop
, unless there already is a current IOLoop
. This behavior
can be controlled with the make_current
argument to the IOLoop
constructor: if make_current=True
, the new IOLoop
will always
try to become current and it raises an error if there is already a
current instance. If make_current=False
, the new IOLoop
will
not try to become current.
In general, an IOLoop
cannot survive a fork or be shared across
processes in any way. When multiple processes are being used, each
process should create its own IOLoop
, which also implies that
any objects which depend on the IOLoop
(such as
AsyncHTTPClient
) must also be created in the child processes.
As a guideline, anything that starts processes (including the
tornado.process
and multiprocessing
modules) should do so as
early as possible, ideally the first thing the application does
after loading its configuration in main()
.
Changed in version 4.2: Added the make_current
keyword argument to the IOLoop
constructor.
Running an IOLoop
static IOLoop.current()[source]
Returns the current thread’s IOLoop
.
If an IOLoop
is currently running or has been marked as
current by make_current
, returns that instance. If there is
no current IOLoop
and instance
is true, creates one.
Changed in version 4.1: Added instance
argument to control the fallback to
IOLoop.instance()
.
Changed in version 5.0: On Python 3, control of the current IOLoop
is delegated
to asyncio
, with this and other methods as pass-through accessors.
The instance
argument now controls whether an IOLoop
is created automatically when there is none, instead of
whether we fall back to IOLoop.instance()
(which is now
an alias for this method). instance=False
is deprecated,
since even if we do not create an IOLoop
, this method
may initialize the asyncio loop.
IOLoop.make_current()[source]
Makes this the IOLoop
for the current thread.
An IOLoop
automatically becomes current for its thread
when it is started, but it is sometimes useful to call
make_current
explicitly before starting the IOLoop
,
so that code run at startup time can find the right
instance.
Changed in version 4.1: An IOLoop
created while there is no current IOLoop
will automatically become current.
Changed in version 5.0: This method also sets the current asyncio
event loop.
static IOLoop.clear_current()[source]
Clears the IOLoop
for the current thread.
Intended primarily for use by test frameworks in between tests.
Changed in version 5.0: This method also clears the current asyncio
event loop.
IOLoop.start()[source]
Starts the I/O loop.
The loop will run until one of the callbacks calls stop()
, which
will make the loop stop after the current event iteration completes.
IOLoop.stop()[source]
Stop the I/O loop.
If the event loop is not currently running, the next call to start()
will return immediately.
To use asynchronous methods from otherwise-synchronous code (such as unit tests), you can start and stop the event loop like this:
ioloop = IOLoop()
async_method(ioloop=ioloop, callback=ioloop.stop)
ioloop.start()
ioloop.start()
will return after async_method
has run
its callback, whether that callback was invoked before or
after ioloop.start
.
Note that even after stop
has been called, the IOLoop
is not
completely stopped until IOLoop.start
has also returned.
Some work that was scheduled before the call to stop
may still
be run before the IOLoop
shuts down.
IOLoop.run_sync(func, timeout=None)[source]
Starts the IOLoop
, runs the given function, and stops the loop.
The function must return either a yieldable object or
None
. If the function returns a yieldable object, the
IOLoop
will run until the yieldable is resolved (and
run_sync()
will return the yieldable’s result). If it raises
an exception, the IOLoop
will stop and the exception will be
re-raised to the caller.
The keyword-only argument timeout
may be used to set
a maximum duration for the function. If the timeout expires,
a tornado.util.TimeoutError
is raised.
This method is useful in conjunction with tornado.gen.coroutine
to allow asynchronous calls in a main()
function:
@gen.coroutine
def main():
# do stuff...
if __name__ == '__main__':
IOLoop.current().run_sync(main)
Changed in version 4.3: Returning a non-None
, non-yieldable value is now an error.
Changed in version 5.0: If a timeout occurs, the func
coroutine will be cancelled.
IOLoop.close(all_fds=False)[source]
Closes the IOLoop
, freeing any resources used.
If all_fds
is true, all file descriptors registered on the
IOLoop will be closed (not just the ones created by the
IOLoop
itself).
Many applications will only use a single IOLoop
that runs for the
entire lifetime of the process. In that case closing the IOLoop
is not necessary since everything will be cleaned up when the
process exits. IOLoop.close
is provided mainly for scenarios
such as unit tests, which create and destroy a large number of
IOLoops
.
An IOLoop
must be completely stopped before it can be closed. This
means that IOLoop.stop()
must be called and IOLoop.start()
must
be allowed to return before attempting to call IOLoop.close()
.
Therefore the call to close
will usually appear just after
the call to start
rather than near the call to stop
.
Changed in version 3.1: If the IOLoop
implementation supports non-integer objects
for “file descriptors”, those objects will have their
close
method when all_fds
is true.
static IOLoop.instance()[source]
Deprecated alias for IOLoop.current()
.
Changed in version 5.0: Previously, this method returned a global singleton
IOLoop
, in contrast with the per-thread IOLoop
returned
by current()
. In nearly all cases the two were the same
(when they differed, it was generally used from non-Tornado
threads to communicate back to the main thread’s IOLoop
).
This distinction is not present in asyncio
, so in order
to facilitate integration with that package instance()
was changed to be an alias to current()
. Applications
using the cross-thread communications aspect of
instance()
should instead set their own global variable
to point to the IOLoop
they want to use.
Deprecated since version 5.0.
IOLoop.install()[source]
Deprecated alias for make_current()
.
Changed in version 5.0: Previously, this method would set this IOLoop
as the
global singleton used by IOLoop.instance()
. Now that
instance()
is an alias for current()
, install()
is an alias for make_current()
.
Deprecated since version 5.0.
static IOLoop.clear_instance()[source]
Deprecated alias for clear_current()
.
Changed in version 5.0: Previously, this method would clear the IOLoop
used as
the global singleton by IOLoop.instance()
. Now that
instance()
is an alias for current()
,
clear_instance()
is an alias for clear_current()
.
Deprecated since version 5.0.
I/O events
IOLoop.add_handler(fd, handler, events)[source]
Registers the given handler to receive the given events for fd
.
The fd
argument may either be an integer file descriptor or
a file-like object with a fileno()
method (and optionally a
close()
method, which may be called when the IOLoop
is shut
down).
The events
argument is a bitwise or of the constants
IOLoop.READ
, IOLoop.WRITE
, and IOLoop.ERROR
.
When an event occurs, handler(fd, events)
will be run.
Changed in version 4.0: Added the ability to pass file-like objects in addition to raw file descriptors.
IOLoop.update_handler(fd, events)[source]
Changes the events we listen for fd
.
Changed in version 4.0: Added the ability to pass file-like objects in addition to raw file descriptors.
IOLoop.remove_handler(fd)[source]
Stop listening for events on fd
.
Changed in version 4.0: Added the ability to pass file-like objects in addition to raw file descriptors.
Callbacks and timeouts
IOLoop.add_callback(callback, *args, **kwargs)[source]
Calls the given callback on the next I/O loop iteration.
It is safe to call this method from any thread at any time,
except from a signal handler. Note that this is the only
method in IOLoop
that makes this thread-safety guarantee; all
other interaction with the IOLoop
must be done from that
IOLoop
’s thread. add_callback()
may be used to transfer
control from other threads to the IOLoop
’s thread.
To add a callback from a signal handler, see
add_callback_from_signal
.
IOLoop.add_callback_from_signal(callback, *args, **kwargs)[source]
Calls the given callback on the next I/O loop iteration.
Safe for use from a Python signal handler; should not be used otherwise.
Callbacks added with this method will be run without any
stack_context
, to avoid picking up the context of the function
that was interrupted by the signal.
IOLoop.add_future(future, callback)[source]
Schedules a callback on the IOLoop
when the given
Future
is finished.
The callback is invoked with one argument, the
Future
.
IOLoop.add_timeout(deadline, callback, *args, **kwargs)[source]
Runs the callback
at the time deadline
from the I/O loop.
Returns an opaque handle that may be passed to
remove_timeout
to cancel.
deadline
may be a number denoting a time (on the same
scale as IOLoop.time
, normally time.time
), or a
datetime.timedelta
object for a deadline relative to the
current time. Since Tornado 4.0, call_later
is a more
convenient alternative for the relative case since it does not
require a timedelta object.
Note that it is not safe to call add_timeout
from other threads.
Instead, you must use add_callback
to transfer control to the
IOLoop
’s thread, and then call add_timeout
from there.
Subclasses of IOLoop must implement either add_timeout
or
call_at
; the default implementations of each will call
the other. call_at
is usually easier to implement, but
subclasses that wish to maintain compatibility with Tornado
versions prior to 4.0 must use add_timeout
instead.
Changed in version 4.0: Now passes through *args
and **kwargs
to the callback.
IOLoop.call_at(when, callback, *args, **kwargs)[source]
Runs the callback
at the absolute time designated by when
.
when
must be a number using the same reference point as
IOLoop.time
.
Returns an opaque handle that may be passed to remove_timeout
to cancel. Note that unlike the asyncio
method of the same
name, the returned object does not have a cancel()
method.
See add_timeout
for comments on thread-safety and subclassing.
New in version 4.0.
IOLoop.call_later(delay, callback, *args, **kwargs)[source]
Runs the callback
after delay
seconds have passed.
Returns an opaque handle that may be passed to remove_timeout
to cancel. Note that unlike the asyncio
method of the same
name, the returned object does not have a cancel()
method.
See add_timeout
for comments on thread-safety and subclassing.
New in version 4.0.
IOLoop.remove_timeout(timeout)[source]
Cancels a pending timeout.
The argument is a handle as returned by add_timeout
. It is
safe to call remove_timeout
even if the callback has already
been run.
IOLoop.spawn_callback(callback, *args, **kwargs)[source]
Calls the given callback on the next IOLoop iteration.
Unlike all other callback-related methods on IOLoop,
spawn_callback
does not associate the callback with its caller’s
stack_context
, so it is suitable for fire-and-forget callbacks
that should not interfere with the caller.
New in version 4.0.
IOLoop.run_in_executor(executor, func, *args)[source]
Runs a function in a concurrent.futures.Executor
. If
executor
is None
, the IO loop’s default executor will be used.
Use functools.partial
to pass keyword arguments to func
.
New in version 5.0.
IOLoop.set_default_executor(executor)[source]
Sets the default executor to use with run_in_executor()
.
New in version 5.0.
IOLoop.time()[source]
Returns the current time according to the IOLoop
’s clock.
The return value is a floating-point number relative to an unspecified time in the past.
By default, the IOLoop
’s time function is time.time
. However,
it may be configured to use e.g. time.monotonic
instead.
Calls to add_timeout
that pass a number instead of a
datetime.timedelta
should use this function to compute the
appropriate time, so they can work no matter what time function
is chosen.
class tornado.ioloop.PeriodicCallback(callback, callback_time)[source]
Schedules the given callback to be called periodically.
The callback is called every callback_time
milliseconds.
Note that the timeout is given in milliseconds, while most other
time-related functions in Tornado use seconds.
If the callback runs for longer than callback_time
milliseconds,
subsequent invocations will be skipped to get back on schedule.
start
must be called after the PeriodicCallback
is created.
Changed in version 5.0: The io_loop
argument (deprecated since version 4.1) has been removed.
start()[source]
Starts the timer.
stop()[source]
Stops the timer.
is_running()[source]
Return True if this PeriodicCallback
has been started.
New in version 4.1.
Debugging and error handling
IOLoop.handle_callback_exception(callback)[source]
This method is called whenever a callback run by the IOLoop
throws an exception.
By default simply logs the exception as an error. Subclasses may override this method to customize reporting of exceptions.
The exception itself is not passed explicitly, but is available
in sys.exc_info
.
IOLoop.set_blocking_signal_threshold(seconds, action)[source]
Sends a signal if the IOLoop
is blocked for more than
s
seconds.
Pass seconds=None
to disable. Requires Python 2.6 on a unixy
platform.
The action parameter is a Python signal handler. Read the
documentation for the signal
module for more information.
If action
is None, the process will be killed if it is
blocked for too long.
Deprecated since version 5.0: Not implemented on the asyncio
event loop. Use the environment
variable PYTHONASYNCIODEBUG=1
instead.
IOLoop.set_blocking_log_threshold(seconds)[source]
Logs a stack trace if the IOLoop
is blocked for more than
s
seconds.
Equivalent to set_blocking_signal_threshold(seconds,
self.log_stack)
Deprecated since version 5.0: Not implemented on the asyncio
event loop. Use the environment
variable PYTHONASYNCIODEBUG=1
instead.
IOLoop.log_stack(signal, frame)[source]
Signal handler to log the stack trace of the current thread.
For use with set_blocking_signal_threshold
.
Methods for subclasses
IOLoop.initialize(make_current=None)[source]
IOLoop.close_fd(fd)[source]
Utility method to close an fd
.
If fd
is a file-like object, we close it directly; otherwise
we use os.close
.
This method is provided for use by IOLoop
subclasses (in
implementations of IOLoop.close(all_fds=True)
and should
not generally be used by application code.
New in version 4.0.
IOLoop.split_fd(fd)[source]
Returns an (fd, obj) pair from an fd
parameter.
We accept both raw file descriptors and file-like objects as
input to add_handler
and related methods. When a file-like
object is passed, we must retain the object itself so we can
close it correctly when the IOLoop
shuts down, but the
poller interfaces favor file descriptors (they will accept
file-like objects and call fileno()
for you, but they
always return the descriptor itself).
This method is provided for use by IOLoop
subclasses and should
not generally be used by application code.
New in version 4.0.