Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1016 lines (840 sloc) 39.449 kb
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
1 #!/usr/bin/env python
2 #
3 # Copyright 2009 Facebook
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16
6d5ebab Ben Darnell IOLoop and HTTPClient docs
bdarnell authored
17 """An I/O event loop for non-blocking sockets.
18
19 Typical applications will use a single `IOLoop` object, in the
20 `IOLoop.instance` singleton. The `IOLoop.start` method should usually
21 be called at the end of the ``main()`` function. Atypical applications may
22 use more than one `IOLoop`, such as one `IOLoop` per thread, or per `unittest`
23 case.
24
25 In addition to I/O events, the `IOLoop` can also schedule time-based events.
26 `IOLoop.add_timeout` is a non-blocking alternative to `time.sleep`.
27 """
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
28
65df55d Ben Darnell Convert print to a function and add future imports.
bdarnell authored
29 from __future__ import absolute_import, division, print_function, with_statement
2ee58f1 Ben Darnell Fix race condition in cross-thread IOLoop.add_callback
bdarnell authored
30
688d59d Ben Darnell Accept timedelta objects in IOLoop.add_timeout.
bdarnell authored
31 import datetime
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
32 import errno
cb2c088 Ben Darnell Add IOLoop.add_future to return to the IOLoop after a future has complet...
bdarnell authored
33 import functools
b6c4d6d Ben Darnell Change IOLoop._timeouts from a sorted list to a heapq.
bdarnell authored
34 import heapq
5fc96e6 Drew Winstel ioloop.py: use itertools.count() as tiebreaker to preserve FIFO in case ...
drewbrew authored
35 import itertools
7b45811 Be consistent in platform checks: use os.name == 'nt' everywhere, repla...
Ben Darnell authored
36 import logging
ed78651 Ben Darnell Get autoreload working in py3 without 2to3.
bdarnell authored
37 import numbers
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
38 import os
7b45811 Be consistent in platform checks: use os.name == 'nt' everywhere, repla...
Ben Darnell authored
39 import select
b8063e4 Ben Darnell Introduce TracebackFuture and use it where applicable.
bdarnell authored
40 import sys
2ee58f1 Ben Darnell Fix race condition in cross-thread IOLoop.add_callback
bdarnell authored
41 import threading
7b45811 Be consistent in platform checks: use os.name == 'nt' everywhere, repla...
Ben Darnell authored
42 import time
b686d6d Add an option to log a stack trace any time the ioloop is blocked for
Ben Darnell authored
43 import traceback
a5e7ee7 Philipp Engel modified method _schedule_next of PeriodicCallback to handle sudden chan...
nosyjoe authored
44 import math
b686d6d Add an option to log a stack trace any time the ioloop is blocked for
Ben Darnell authored
45
dce2ffe Ben Darnell tornado.concurrent.Future is now always thread-unsafe.
bdarnell authored
46 from tornado.concurrent import TracebackFuture, is_future
9b944aa Ben Darnell Switch from root logger to separate loggers.
bdarnell authored
47 from tornado.log import app_log, gen_log
28adce3 Make all internal imports of tornado modules absolute
Ben Darnell authored
48 from tornado import stack_context
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
49 from tornado.util import Configurable, errno_from_exception, timedelta_to_seconds
28adce3 Make all internal imports of tornado modules absolute
Ben Darnell authored
50
b686d6d Add an option to log a stack trace any time the ioloop is blocked for
Ben Darnell authored
51 try:
52 import signal
53 except ImportError:
54 signal = None
7b45811 Be consistent in platform checks: use os.name == 'nt' everywhere, repla...
Ben Darnell authored
55
cb2c088 Ben Darnell Add IOLoop.add_future to return to the IOLoop after a future has complet...
bdarnell authored
56 try:
051cd60 Ben Darnell Checkpoint: tests can now be imported in python 3 without 2to3.
bdarnell authored
57 import thread # py2
58 except ImportError:
59 import _thread as thread # py3
60
2963eed Ben Darnell Move the waker pipe into tornado.platform.
bdarnell authored
61 from tornado.platform.auto import set_close_exec, Waker
7e0e73b Ben Darnell Clean up hacky fcntl emulation for windows.
bdarnell authored
62
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
63
fa41dd7 Marc Schlaich Make poll timeout patchable.
schlamar authored
64 _POLL_TIMEOUT = 3600.0
65
66
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
67 class TimeoutError(Exception):
68 pass
69
70
91c5eb8 Ben Darnell Extract configure logic from AsyncHTTPClient to a base class.
bdarnell authored
71 class IOLoop(Configurable):
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
72 """A level-triggered I/O loop.
73
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
74 We use ``epoll`` (Linux) or ``kqueue`` (BSD and Mac OS X) if they
75 are available, or else we fall back on select(). If you are
76 implementing a system that needs to handle thousands of
77 simultaneous connections, you should use a system that supports
78 either ``epoll`` or ``kqueue``.
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
79
b93b840 Ben Darnell Make many doc code blocks into sphinx doctests.
bdarnell authored
80 Example usage for a simple TCP server:
81
82 .. testcode::
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
83
84 import errno
85 import functools
b93b840 Ben Darnell Make many doc code blocks into sphinx doctests.
bdarnell authored
86 import tornado.ioloop
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
87 import socket
88
89 def connection_ready(sock, fd, events):
90 while True:
91 try:
92 connection, address = sock.accept()
b93b840 Ben Darnell Make many doc code blocks into sphinx doctests.
bdarnell authored
93 except socket.error as e:
4118b8e Changed e[0] to e.args[0]
Szabó Antal authored
94 if e.args[0] not in (errno.EWOULDBLOCK, errno.EAGAIN):
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
95 raise
96 return
97 connection.setblocking(0)
98 handle_connection(connection, address)
99
b93b840 Ben Darnell Make many doc code blocks into sphinx doctests.
bdarnell authored
100 if __name__ == '__main__':
101 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
102 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
103 sock.setblocking(0)
104 sock.bind(("", port))
105 sock.listen(128)
106
107 io_loop = tornado.ioloop.IOLoop.instance()
108 callback = functools.partial(connection_ready, sock)
109 io_loop.add_handler(sock.fileno(), callback, io_loop.READ)
110 io_loop.start()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
111
b93b840 Ben Darnell Make many doc code blocks into sphinx doctests.
bdarnell authored
112 .. testoutput::
113 :hide:
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
114
115 """
116 # Constants from the epoll module
117 _EPOLLIN = 0x001
118 _EPOLLPRI = 0x002
119 _EPOLLOUT = 0x004
120 _EPOLLERR = 0x008
121 _EPOLLHUP = 0x010
122 _EPOLLRDHUP = 0x2000
123 _EPOLLONESHOT = (1 << 30)
124 _EPOLLET = (1 << 31)
125
126 # Our events map exactly to the epoll events
127 NONE = 0
128 READ = _EPOLLIN
129 WRITE = _EPOLLOUT
8572cc4 Ben Darnell Fix connection-close detection for epoll.
bdarnell authored
130 ERROR = _EPOLLERR | _EPOLLHUP
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
131
840392f Andrej Antonov double-checked-locking in tornado.ioloop.IOLoop.instance()
polymorphm authored
132 # Global lock for creating global IOLoop instance
133 _instance_lock = threading.Lock()
134
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
135 _current = threading.local()
136
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
137 @staticmethod
138 def instance():
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
139 """Returns a global `IOLoop` instance.
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
140
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
141 Most applications have a single, global `IOLoop` running on the
142 main thread. Use this method to get this instance from
143 another thread. To get the current thread's `IOLoop`, use `current()`.
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
144 """
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
145 if not hasattr(IOLoop, "_instance"):
840392f Andrej Antonov double-checked-locking in tornado.ioloop.IOLoop.instance()
polymorphm authored
146 with IOLoop._instance_lock:
147 if not hasattr(IOLoop, "_instance"):
148 # New instance after double check
149 IOLoop._instance = IOLoop()
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
150 return IOLoop._instance
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
151
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
152 @staticmethod
153 def initialized():
55d3be1 Ben Darnell Run coverage check and fill in the blanks
bdarnell authored
154 """Returns true if the singleton instance has been created."""
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
155 return hasattr(IOLoop, "_instance")
156
157 def install(self):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
158 """Installs this `IOLoop` object as the singleton instance.
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
159
160 This is normally not necessary as `instance()` will create
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
161 an `IOLoop` on demand, but you may want to call `install` to use
162 a custom subclass of `IOLoop`.
6ec7b47 Ben Darnell Add install() method to IOLoop to allow a custom subclass as the singlet...
bdarnell authored
163 """
164 assert not IOLoop.initialized()
165 IOLoop._instance = self
6fb90ae Pre-forking implementation so a single Tornado server can utilize all CP...
Bret Taylor authored
166
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
167 @staticmethod
dd45026 Min RK add IOLoop.clear_instance
minrk authored
168 def clear_instance():
425a31d Ben Darnell Document all the new HTTP stuff
bdarnell authored
169 """Clear the global `IOLoop` instance.
170
00229a2 Ben Darnell The next version will be 4.0, not 3.3, so update all references to 3.3.
bdarnell authored
171 .. versionadded:: 4.0
425a31d Ben Darnell Document all the new HTTP stuff
bdarnell authored
172 """
dd45026 Min RK add IOLoop.clear_instance
minrk authored
173 if hasattr(IOLoop, "_instance"):
174 del IOLoop._instance
175
176 @staticmethod
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
177 def current(instance=True):
059f0e8 Ben Darnell Rename WebSocketConnect to websocket_connect.
bdarnell authored
178 """Returns the current thread's `IOLoop`.
179
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
180 If an `IOLoop` is currently running or has been marked as
181 current by `make_current`, returns that instance. If there is
182 no current `IOLoop`, returns `IOLoop.instance()` (i.e. the
183 main thread's `IOLoop`, creating one if necessary) if ``instance``
184 is true.
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
185
059f0e8 Ben Darnell Rename WebSocketConnect to websocket_connect.
bdarnell authored
186 In general you should use `IOLoop.current` as the default when
187 constructing an asynchronous object, and use `IOLoop.instance`
188 when you mean to communicate to the main thread from a different
189 one.
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
190
191 .. versionchanged:: 4.1
192 Added ``instance`` argument to control the
193
059f0e8 Ben Darnell Rename WebSocketConnect to websocket_connect.
bdarnell authored
194 """
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
195 current = getattr(IOLoop._current, "instance", None)
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
196 if current is None and instance:
2ad9659 Ben Darnell All functions that take an IOLoop default to current() instead of instan...
bdarnell authored
197 return IOLoop.instance()
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
198 return current
199
200 def make_current(self):
059f0e8 Ben Darnell Rename WebSocketConnect to websocket_connect.
bdarnell authored
201 """Makes this the `IOLoop` for the current thread.
202
203 An `IOLoop` automatically becomes current for its thread
204 when it is started, but it is sometimes useful to call
61e87cd Kyoung-chan Lee Fixed some typos
leekchan authored
205 `make_current` explicitly before starting the `IOLoop`,
059f0e8 Ben Darnell Rename WebSocketConnect to websocket_connect.
bdarnell authored
206 so that code run at startup time can find the right
207 instance.
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
208
209 .. versionchanged:: 4.1
210 An `IOLoop` created while there is no current `IOLoop`
211 will automatically become current.
059f0e8 Ben Darnell Rename WebSocketConnect to websocket_connect.
bdarnell authored
212 """
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
213 IOLoop._current.instance = self
214
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
215 @staticmethod
216 def clear_current():
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
217 IOLoop._current.instance = None
218
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
219 @classmethod
220 def configurable_base(cls):
221 return IOLoop
222
223 @classmethod
224 def configurable_default(cls):
217b7eb Ben Darnell Remove our custom epoll module now that we only support 2.6+.
bdarnell authored
225 if hasattr(select, "epoll"):
226 from tornado.platform.epoll import EPollIOLoop
227 return EPollIOLoop
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
228 if hasattr(select, "kqueue"):
229 # Python 2.6+ on BSD or Mac
230 from tornado.platform.kqueue import KQueueIOLoop
231 return KQueueIOLoop
232 from tornado.platform.select import SelectIOLoop
233 return SelectIOLoop
234
235 def initialize(self):
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
236 if IOLoop.current(instance=False) is None:
237 self.make_current()
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
238
9d1af05 Ben Darnell Clean up shutdown process for IOLoop and HTTPClient.
bdarnell authored
239 def close(self, all_fds=False):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
240 """Closes the `IOLoop`, freeing any resources used.
6ac8a05 Evan Klitzke improve the speed of add_callback by avoiding the waker pipe when possib...
eklitzke authored
241
9d1af05 Ben Darnell Clean up shutdown process for IOLoop and HTTPClient.
bdarnell authored
242 If ``all_fds`` is true, all file descriptors registered on the
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
243 IOLoop will be closed (not just the ones created by the
244 `IOLoop` itself).
2f0fbd9 Ben Darnell Expand documentation for IOLoop.stop and IOLoop.close
bdarnell authored
245
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
246 Many applications will only use a single `IOLoop` that runs for the
247 entire lifetime of the process. In that case closing the `IOLoop`
2f0fbd9 Ben Darnell Expand documentation for IOLoop.stop and IOLoop.close
bdarnell authored
248 is not necessary since everything will be cleaned up when the
249 process exits. `IOLoop.close` is provided mainly for scenarios
250 such as unit tests, which create and destroy a large number of
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
251 ``IOLoops``.
2f0fbd9 Ben Darnell Expand documentation for IOLoop.stop and IOLoop.close
bdarnell authored
252
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
253 An `IOLoop` must be completely stopped before it can be closed. This
2f0fbd9 Ben Darnell Expand documentation for IOLoop.stop and IOLoop.close
bdarnell authored
254 means that `IOLoop.stop()` must be called *and* `IOLoop.start()` must
255 be allowed to return before attempting to call `IOLoop.close()`.
256 Therefore the call to `close` will usually appear just after
257 the call to `start` rather than near the call to `stop`.
d68b629 Ben Darnell Add versionadded tags throughout the docs.
bdarnell authored
258
259 .. versionchanged:: 3.1
260 If the `IOLoop` implementation supports non-integer objects
261 for "file descriptors", those objects will have their
262 ``close`` method when ``all_fds`` is true.
9d1af05 Ben Darnell Clean up shutdown process for IOLoop and HTTPClient.
bdarnell authored
263 """
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
264 raise NotImplementedError()
9d1af05 Ben Darnell Clean up shutdown process for IOLoop and HTTPClient.
bdarnell authored
265
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
266 def add_handler(self, fd, handler, events):
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
267 """Registers the given handler to receive the given events for ``fd``.
268
269 The ``fd`` argument may either be an integer file descriptor or
270 a file-like object with a ``fileno()`` method (and optionally a
271 ``close()`` method, which may be called when the `IOLoop` is shut
272 down).
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
273
274 The ``events`` argument is a bitwise or of the constants
275 ``IOLoop.READ``, ``IOLoop.WRITE``, and ``IOLoop.ERROR``.
276
277 When an event occurs, ``handler(fd, events)`` will be run.
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
278
00229a2 Ben Darnell The next version will be 4.0, not 3.3, so update all references to 3.3.
bdarnell authored
279 .. versionchanged:: 4.0
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
280 Added the ability to pass file-like objects in addition to
281 raw file descriptors.
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
282 """
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
283 raise NotImplementedError()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
284
285 def update_handler(self, fd, events):
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
286 """Changes the events we listen for ``fd``.
287
00229a2 Ben Darnell The next version will be 4.0, not 3.3, so update all references to 3.3.
bdarnell authored
288 .. versionchanged:: 4.0
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
289 Added the ability to pass file-like objects in addition to
290 raw file descriptors.
291 """
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
292 raise NotImplementedError()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
293
294 def remove_handler(self, fd):
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
295 """Stop listening for events on ``fd``.
296
00229a2 Ben Darnell The next version will be 4.0, not 3.3, so update all references to 3.3.
bdarnell authored
297 .. versionchanged:: 4.0
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
298 Added the ability to pass file-like objects in addition to
299 raw file descriptors.
300 """
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
301 raise NotImplementedError()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
302
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
303 def set_blocking_signal_threshold(self, seconds, action):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
304 """Sends a signal if the `IOLoop` is blocked for more than
305 ``s`` seconds.
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
306
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
307 Pass ``seconds=None`` to disable. Requires Python 2.6 on a unixy
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
308 platform.
309
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
310 The action parameter is a Python signal handler. Read the
311 documentation for the `signal` module for more information.
312 If ``action`` is None, the process will be killed if it is
313 blocked for too long.
b686d6d Add an option to log a stack trace any time the ioloop is blocked for
Ben Darnell authored
314 """
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
315 raise NotImplementedError()
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
316
317 def set_blocking_log_threshold(self, seconds):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
318 """Logs a stack trace if the `IOLoop` is blocked for more than
319 ``s`` seconds.
320
321 Equivalent to ``set_blocking_signal_threshold(seconds,
322 self.log_stack)``
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
323 """
9f529b8 Ben Darnell Fix improperly-renamed variable in set_blocking_signal_threshold
bdarnell authored
324 self.set_blocking_signal_threshold(seconds, self.log_stack)
b686d6d Add an option to log a stack trace any time the ioloop is blocked for
Ben Darnell authored
325
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
326 def log_stack(self, signal, frame):
327 """Signal handler to log the stack trace of the current thread.
328
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
329 For use with `set_blocking_signal_threshold`.
f46cfa4 Ben Darnell Generalize IOLoop.set_blocking_log_threshold by allowing user-specified
bdarnell authored
330 """
9b944aa Ben Darnell Switch from root logger to separate loggers.
bdarnell authored
331 gen_log.warning('IOLoop blocked for %f seconds in\n%s',
e582e58 Ben Darnell Update autopep8 to 0.8.5 and run it.
bdarnell authored
332 self._blocking_signal_threshold,
333 ''.join(traceback.format_stack(frame)))
b686d6d Add an option to log a stack trace any time the ioloop is blocked for
Ben Darnell authored
334
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
335 def start(self):
336 """Starts the I/O loop.
337
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
338 The loop will run until one of the callbacks calls `stop()`, which
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
339 will make the loop stop after the current event iteration completes.
340 """
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
341 raise NotImplementedError()
342
1a2460c Ben Darnell Move _setup_logging to BaseIOLoop and use it in asyncio and twisted impl...
bdarnell authored
343 def _setup_logging(self):
344 """The IOLoop catches and logs exceptions, so it's
345 important that log output be visible. However, python's
346 default behavior for non-root loggers (prior to python
347 3.2) is to print an unhelpful "no handlers could be
348 found" message rather than the actual log entry, so we
349 must explicitly configure logging if we've made it this
350 far without anything.
351
352 This method should be called from start() in subclasses.
353 """
354 if not any([logging.getLogger().handlers,
355 logging.getLogger('tornado').handlers,
356 logging.getLogger('tornado.application').handlers]):
357 logging.basicConfig()
358
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
359 def stop(self):
280c286 Ben Darnell Clarify docstring of IOLoop.stop.
bdarnell authored
360 """Stop the I/O loop.
361
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
362 If the event loop is not currently running, the next call to `start()`
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
363 will return immediately.
364
365 To use asynchronous methods from otherwise-synchronous code (such as
366 unit tests), you can start and stop the event loop like this::
367
368 ioloop = IOLoop()
369 async_method(ioloop=ioloop, callback=ioloop.stop)
370 ioloop.start()
371
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
372 ``ioloop.start()`` will return after ``async_method`` has run
373 its callback, whether that callback was invoked before or
374 after ``ioloop.start``.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
375
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
376 Note that even after `stop` has been called, the `IOLoop` is not
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
377 completely stopped until `IOLoop.start` has also returned.
280c286 Ben Darnell Clarify docstring of IOLoop.stop.
bdarnell authored
378 Some work that was scheduled before the call to `stop` may still
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
379 be run before the `IOLoop` shuts down.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
380 """
381 raise NotImplementedError()
382
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
383 def run_sync(self, func, timeout=None):
384 """Starts the `IOLoop`, runs the given function, and stops the loop.
385
b5a27a3 Ben Darnell Document tornado.concurrent.Future.
bdarnell authored
386 If the function returns a `.Future`, the `IOLoop` will run
387 until the future is resolved. If it raises an exception, the
388 `IOLoop` will stop and the exception will be re-raised to the
389 caller.
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
390
391 The keyword-only argument ``timeout`` may be used to set
392 a maximum duration for the function. If the timeout expires,
393 a `TimeoutError` is raised.
394
395 This method is useful in conjunction with `tornado.gen.coroutine`
9f3dec0 Ben Darnell Fix most of the rest of the dangling references.
bdarnell authored
396 to allow asynchronous calls in a ``main()`` function::
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
397
398 @gen.coroutine
399 def main():
400 # do stuff...
401
402 if __name__ == '__main__':
403 IOLoop.instance().run_sync(main)
404 """
405 future_cell = [None]
9550854 Ben Darnell Re-apply autopep8.
bdarnell authored
406
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
407 def run():
408 try:
409 result = func()
b8063e4 Ben Darnell Introduce TracebackFuture and use it where applicable.
bdarnell authored
410 except Exception:
411 future_cell[0] = TracebackFuture()
412 future_cell[0].set_exc_info(sys.exc_info())
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
413 else:
dce2ffe Ben Darnell tornado.concurrent.Future is now always thread-unsafe.
bdarnell authored
414 if is_future(result):
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
415 future_cell[0] = result
416 else:
8bc337a Ben Darnell Use TracebackFuture for all internal Futures for better tracebacks on py...
bdarnell authored
417 future_cell[0] = TracebackFuture()
80bee0c Ben Darnell Add IOLoop.run_sync convenience method.
bdarnell authored
418 future_cell[0].set_result(result)
419 self.add_future(future_cell[0], lambda future: self.stop())
420 self.add_callback(run)
421 if timeout is not None:
422 timeout_handle = self.add_timeout(self.time() + timeout, self.stop)
423 self.start()
424 if timeout is not None:
425 self.remove_timeout(timeout_handle)
426 if not future_cell[0].done():
427 raise TimeoutError('Operation timed out after %s seconds' % timeout)
428 return future_cell[0].result()
429
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
430 def time(self):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
431 """Returns the current time according to the `IOLoop`'s clock.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
432
433 The return value is a floating-point number relative to an
434 unspecified time in the past.
435
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
436 By default, the `IOLoop`'s time function is `time.time`. However,
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
437 it may be configured to use e.g. `time.monotonic` instead.
438 Calls to `add_timeout` that pass a number instead of a
439 `datetime.timedelta` should use this function to compute the
440 appropriate time, so they can work no matter what time function
441 is chosen.
442 """
443 return time.time()
444
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
445 def add_timeout(self, deadline, callback, *args, **kwargs):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
446 """Runs the ``callback`` at the time ``deadline`` from the I/O loop.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
447
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
448 Returns an opaque handle that may be passed to
449 `remove_timeout` to cancel.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
450
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
451 ``deadline`` may be a number denoting a time (on the same
452 scale as `IOLoop.time`, normally `time.time`), or a
453 `datetime.timedelta` object for a deadline relative to the
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
454 current time. Since Tornado 4.0, `call_later` is a more
455 convenient alternative for the relative case since it does not
456 require a timedelta object.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
457
458 Note that it is not safe to call `add_timeout` from other threads.
459 Instead, you must use `add_callback` to transfer control to the
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
460 `IOLoop`'s thread, and then call `add_timeout` from there.
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
461
462 Subclasses of IOLoop must implement either `add_timeout` or
463 `call_at`; the default implementations of each will call
464 the other. `call_at` is usually easier to implement, but
465 subclasses that wish to maintain compatibility with Tornado
466 versions prior to 4.0 must use `add_timeout` instead.
467
468 .. versionchanged:: 4.0
469 Now passes through ``*args`` and ``**kwargs`` to the callback.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
470 """
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
471 if isinstance(deadline, numbers.Real):
472 return self.call_at(deadline, callback, *args, **kwargs)
473 elif isinstance(deadline, datetime.timedelta):
474 return self.call_at(self.time() + timedelta_to_seconds(deadline),
475 callback, *args, **kwargs)
476 else:
477 raise TypeError("Unsupported deadline %r" % deadline)
478
479 def call_later(self, delay, callback, *args, **kwargs):
480 """Runs the ``callback`` after ``delay`` seconds have passed.
481
482 Returns an opaque handle that may be passed to `remove_timeout`
483 to cancel. Note that unlike the `asyncio` method of the same
484 name, the returned object does not have a ``cancel()`` method.
485
486 See `add_timeout` for comments on thread-safety and subclassing.
487
488 .. versionadded:: 4.0
489 """
a983616 Ben Darnell Add missing return statements to call_at and call_later.
bdarnell authored
490 return self.call_at(self.time() + delay, callback, *args, **kwargs)
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
491
492 def call_at(self, when, callback, *args, **kwargs):
493 """Runs the ``callback`` at the absolute time designated by ``when``.
494
495 ``when`` must be a number using the same reference point as
496 `IOLoop.time`.
497
498 Returns an opaque handle that may be passed to `remove_timeout`
499 to cancel. Note that unlike the `asyncio` method of the same
500 name, the returned object does not have a ``cancel()`` method.
501
502 See `add_timeout` for comments on thread-safety and subclassing.
503
504 .. versionadded:: 4.0
505 """
a983616 Ben Darnell Add missing return statements to call_at and call_later.
bdarnell authored
506 return self.add_timeout(when, callback, *args, **kwargs)
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
507
508 def remove_timeout(self, timeout):
509 """Cancels a pending timeout.
510
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
511 The argument is a handle as returned by `add_timeout`. It is
0126e2e Ben Darnell Document and test the ability to call remove_timeout after it has fired.
bdarnell authored
512 safe to call `remove_timeout` even if the callback has already
513 been run.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
514 """
515 raise NotImplementedError()
516
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
517 def add_callback(self, callback, *args, **kwargs):
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
518 """Calls the given callback on the next I/O loop iteration.
519
520 It is safe to call this method from any thread at any time,
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
521 except from a signal handler. Note that this is the **only**
522 method in `IOLoop` that makes this thread-safety guarantee; all
523 other interaction with the `IOLoop` must be done from that
524 `IOLoop`'s thread. `add_callback()` may be used to transfer
525 control from other threads to the `IOLoop`'s thread.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
526
527 To add a callback from a signal handler, see
528 `add_callback_from_signal`.
529 """
530 raise NotImplementedError()
531
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
532 def add_callback_from_signal(self, callback, *args, **kwargs):
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
533 """Calls the given callback on the next I/O loop iteration.
534
535 Safe for use from a Python signal handler; should not be used
536 otherwise.
537
538 Callbacks added with this method will be run without any
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
539 `.stack_context`, to avoid picking up the context of the function
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
540 that was interrupted by the signal.
541 """
542 raise NotImplementedError()
543
4e9de2e Ben Darnell Introduce IOLoop.spawn_callback.
bdarnell authored
544 def spawn_callback(self, callback, *args, **kwargs):
545 """Calls the given callback on the next IOLoop iteration.
546
547 Unlike all other callback-related methods on IOLoop,
548 ``spawn_callback`` does not associate the callback with its caller's
549 ``stack_context``, so it is suitable for fire-and-forget callbacks
550 that should not interfere with the caller.
551
552 .. versionadded:: 4.0
553 """
554 with stack_context.NullContext():
555 self.add_callback(callback, *args, **kwargs)
556
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
557 def add_future(self, future, callback):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
558 """Schedules a callback on the ``IOLoop`` when the given
b5a27a3 Ben Darnell Document tornado.concurrent.Future.
bdarnell authored
559 `.Future` is finished.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
560
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
561 The callback is invoked with one argument, the
b5a27a3 Ben Darnell Document tornado.concurrent.Future.
bdarnell authored
562 `.Future`.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
563 """
dce2ffe Ben Darnell tornado.concurrent.Future is now always thread-unsafe.
bdarnell authored
564 assert is_future(future)
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
565 callback = stack_context.wrap(callback)
566 future.add_done_callback(
3c24b7b Ben Darnell Remove some now-unnecessary calls to functools.partial
bdarnell authored
567 lambda future: self.add_callback(callback, future))
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
568
569 def _run_callback(self, callback):
570 """Runs a callback with error handling.
571
572 For use in subclasses.
573 """
574 try:
99aa924 Ben Darnell When a function on the IOLoop returns a Future, log its exception.
bdarnell authored
575 ret = callback()
576 if ret is not None and is_future(ret):
577 # Functions that return Futures typically swallow all
578 # exceptions and store them in the Future. If a Future
579 # makes it out to the IOLoop, ensure its exception (if any)
580 # gets logged too.
581 self.add_future(ret, lambda f: f.result())
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
582 except Exception:
583 self.handle_callback_exception(callback)
584
585 def handle_callback_exception(self, callback):
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
586 """This method is called whenever a callback run by the `IOLoop`
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
587 throws an exception.
588
589 By default simply logs the exception as an error. Subclasses
590 may override this method to customize reporting of exceptions.
591
592 The exception itself is not passed explicitly, but is available
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
593 in `sys.exc_info`.
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
594 """
595 app_log.error("Exception in callback %r", callback, exc_info=True)
596
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
597 def split_fd(self, fd):
598 """Returns an (fd, obj) pair from an ``fd`` parameter.
599
600 We accept both raw file descriptors and file-like objects as
601 input to `add_handler` and related methods. When a file-like
602 object is passed, we must retain the object itself so we can
603 close it correctly when the `IOLoop` shuts down, but the
604 poller interfaces favor file descriptors (they will accept
605 file-like objects and call ``fileno()`` for you, but they
606 always return the descriptor itself).
607
608 This method is provided for use by `IOLoop` subclasses and should
609 not generally be used by application code.
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
610
00229a2 Ben Darnell The next version will be 4.0, not 3.3, so update all references to 3.3.
bdarnell authored
611 .. versionadded:: 4.0
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
612 """
613 try:
614 return fd.fileno(), fd
615 except AttributeError:
616 return fd, fd
617
618 def close_fd(self, fd):
619 """Utility method to close an ``fd``.
620
621 If ``fd`` is a file-like object, we close it directly; otherwise
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
622 we use `os.close`.
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
623
624 This method is provided for use by `IOLoop` subclasses (in
625 implementations of ``IOLoop.close(all_fds=True)`` and should
626 not generally be used by application code.
df6db55 Ben Darnell Document file descriptor change and start new release notes.
bdarnell authored
627
00229a2 Ben Darnell The next version will be 4.0, not 3.3, so update all references to 3.3.
bdarnell authored
628 .. versionadded:: 4.0
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
629 """
630 try:
631 try:
632 fd.close()
633 except AttributeError:
634 os.close(fd)
635 except OSError:
636 pass
637
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
638
639 class PollIOLoop(IOLoop):
640 """Base class for IOLoops built around a select-like function.
641
642 For concrete implementations, see `tornado.platform.epoll.EPollIOLoop`
643 (Linux), `tornado.platform.kqueue.KQueueIOLoop` (BSD and Mac), or
644 `tornado.platform.select.SelectIOLoop` (all platforms).
645 """
646 def initialize(self, impl, time_func=None):
647 super(PollIOLoop, self).initialize()
648 self._impl = impl
649 if hasattr(self._impl, 'fileno'):
650 set_close_exec(self._impl.fileno())
651 self.time_func = time_func or time.time
652 self._handlers = {}
653 self._events = {}
654 self._callbacks = []
655 self._callback_lock = threading.Lock()
656 self._timeouts = []
a6d158f Ben Darnell Clean up cancelled timeout handles when the queue gets full of them.
bdarnell authored
657 self._cancellations = 0
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
658 self._running = False
659 self._stopped = False
b724652 Ben Darnell Ensure that add_callback fails cleanly if called while IOLoop is closing...
bdarnell authored
660 self._closing = False
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
661 self._thread_ident = None
662 self._blocking_signal_threshold = None
5fc96e6 Drew Winstel ioloop.py: use itertools.count() as tiebreaker to preserve FIFO in case ...
drewbrew authored
663 self._timeout_counter = itertools.count()
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
664
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
665 # Create a pipe that we send bogus data to when we want to wake
666 # the I/O loop when it is idle
667 self._waker = Waker()
668 self.add_handler(self._waker.fileno(),
669 lambda fd, events: self._waker.consume(),
670 self.READ)
671
672 def close(self, all_fds=False):
b724652 Ben Darnell Ensure that add_callback fails cleanly if called while IOLoop is closing...
bdarnell authored
673 with self._callback_lock:
674 self._closing = True
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
675 self.remove_handler(self._waker.fileno())
676 if all_fds:
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
677 for fd, handler in self._handlers.values():
678 self.close_fd(fd)
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
679 self._waker.close()
680 self._impl.close()
33370aa Ben Darnell Help out the CPython GC by clearing some references in IOLoop.close.
bdarnell authored
681 self._callbacks = None
682 self._timeouts = None
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
683
684 def add_handler(self, fd, handler, events):
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
685 fd, obj = self.split_fd(fd)
686 self._handlers[fd] = (obj, stack_context.wrap(handler))
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
687 self._impl.register(fd, events | self.ERROR)
688
689 def update_handler(self, fd, events):
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
690 fd, obj = self.split_fd(fd)
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
691 self._impl.modify(fd, events | self.ERROR)
692
693 def remove_handler(self, fd):
7552cae Ben Darnell Allow and encourage the use of file objects instead of integer fds in IO...
bdarnell authored
694 fd, obj = self.split_fd(fd)
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
695 self._handlers.pop(fd, None)
696 self._events.pop(fd, None)
697 try:
698 self._impl.unregister(fd)
c6593a3 Ben Darnell Catch all exceptions, not just {OS,IO}Error in IOLoop.remove_handler.
bdarnell authored
699 except Exception:
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
700 gen_log.debug("Error deleting fd from IOLoop", exc_info=True)
701
702 def set_blocking_signal_threshold(self, seconds, action):
703 if not hasattr(signal, "setitimer"):
704 gen_log.error("set_blocking_signal_threshold requires a signal module "
e582e58 Ben Darnell Update autopep8 to 0.8.5 and run it.
bdarnell authored
705 "with the setitimer method")
1a66183 Ben Darnell Split IOLoop into a base class and poll-based implementation.
bdarnell authored
706 return
707 self._blocking_signal_threshold = seconds
708 if seconds is not None:
709 signal.signal(signal.SIGALRM,
710 action if action is not None else signal.SIG_DFL)
711
6e287d8 Gavin M. Roy Don't call logging.basicConfig if logging is already configured (#775).
gmr authored
712 def start(self):
869fb74 Ben Darnell Raise an error if IOLoop.start() is called while it is already running.
bdarnell authored
713 if self._running:
714 raise RuntimeError("IOLoop is already running")
6e287d8 Gavin M. Roy Don't call logging.basicConfig if logging is already configured (#775).
gmr authored
715 self._setup_logging()
3ab6390 If IOLoop.stop is called before the loop is running, make the next
Ben Darnell authored
716 if self._stopped:
717 self._stopped = False
718 return
0cc0df7 Ben Darnell Add magic for yielding futures.
bdarnell authored
719 old_current = getattr(IOLoop._current, "instance", None)
720 IOLoop._current.instance = self
6ac8a05 Evan Klitzke improve the speed of add_callback by avoiding the waker pipe when possib...
eklitzke authored
721 self._thread_ident = thread.get_ident()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
722 self._running = True
18af6c7 Ben Darnell Use signal.set_wakeup_fd in IOLoop to close a race with signal handlers.
bdarnell authored
723
724 # signal.set_wakeup_fd closes a race condition in event loops:
725 # a signal may arrive at the beginning of select/poll/etc
726 # before it goes into its interruptible sleep, so the signal
727 # will be consumed without waking the select. The solution is
728 # for the (C, synchronous) signal handler to write to a pipe,
729 # which will then be seen by select.
730 #
731 # In python's signal handling semantics, this only matters on the
732 # main thread (fortunately, set_wakeup_fd only works on the main
733 # thread and will raise a ValueError otherwise).
734 #
735 # If someone has already set a wakeup fd, we don't want to
736 # disturb it. This is an issue for twisted, which does its
1e1d61a Ben Darnell s/SIGCHILD/SIGCHLD/ in docs.
bdarnell authored
737 # SIGCHLD processing in response to its own wakeup fd being
18af6c7 Ben Darnell Use signal.set_wakeup_fd in IOLoop to close a race with signal handlers.
bdarnell authored
738 # written to. As long as the wakeup fd is registered on the IOLoop,
739 # the loop will still wake up and everything should work.
740 old_wakeup_fd = None
a8a7ee4 Ben Darnell Don't try to call set_wakeup_fd on windows, it crashes the process.
bdarnell authored
741 if hasattr(signal, 'set_wakeup_fd') and os.name == 'posix':
742 # requires python 2.6+, unix. set_wakeup_fd exists but crashes
743 # the python process on windows.
18af6c7 Ben Darnell Use signal.set_wakeup_fd in IOLoop to close a race with signal handlers.
bdarnell authored
744 try:
745 old_wakeup_fd = signal.set_wakeup_fd(self._waker.write_fileno())
ae7cfe4 Ben Darnell Add IOLoop.add_callback_from_signal, which avoids deadlocks
bdarnell authored
746 if old_wakeup_fd != -1:
747 # Already set, restore previous value. This is a little racy,
748 # but there's no clean get_wakeup_fd and in real use the
749 # IOLoop is just started once at the beginning.
750 signal.set_wakeup_fd(old_wakeup_fd)
751 old_wakeup_fd = None
18af6c7 Ben Darnell Use signal.set_wakeup_fd in IOLoop to close a race with signal handlers.
bdarnell authored
752 except ValueError: # non-main thread
753 pass
754
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
755 try:
756 while True:
757 # Prevent IO event starvation by delaying new callbacks
758 # to the next iteration of the event loop.
759 with self._callback_lock:
760 callbacks = self._callbacks
761 self._callbacks = []
762
1591ade Ben Darnell Improve callback scheduling.
bdarnell authored
763 # Add any timeouts that have come due to the callback list.
764 # Do not run anything until we have determined which ones
765 # are ready, so timeouts that call add_timeout cannot
766 # schedule anything in this iteration.
6303359 Ben Darnell Fix a regression in which a timeout could fire after being cancelled.
bdarnell authored
767 due_timeouts = []
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
768 if self._timeouts:
769 now = self.time()
770 while self._timeouts:
771 if self._timeouts[0].callback is None:
6303359 Ben Darnell Fix a regression in which a timeout could fire after being cancelled.
bdarnell authored
772 # The timeout was cancelled. Note that the
773 # cancellation check is repeated below for timeouts
774 # that are cancelled by another timeout or callback.
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
775 heapq.heappop(self._timeouts)
776 self._cancellations -= 1
777 elif self._timeouts[0].deadline <= now:
6303359 Ben Darnell Fix a regression in which a timeout could fire after being cancelled.
bdarnell authored
778 due_timeouts.append(heapq.heappop(self._timeouts))
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
779 else:
780 break
781 if (self._cancellations > 512
782 and self._cancellations > (len(self._timeouts) >> 1)):
783 # Clean up the timeout queue when it gets large and it's
784 # more than half cancellations.
785 self._cancellations = 0
786 self._timeouts = [x for x in self._timeouts
787 if x.callback is not None]
788 heapq.heapify(self._timeouts)
789
1591ade Ben Darnell Improve callback scheduling.
bdarnell authored
790 for callback in callbacks:
791 self._run_callback(callback)
6303359 Ben Darnell Fix a regression in which a timeout could fire after being cancelled.
bdarnell authored
792 for timeout in due_timeouts:
793 if timeout.callback is not None:
794 self._run_callback(timeout.callback)
1591ade Ben Darnell Improve callback scheduling.
bdarnell authored
795 # Closures may be holding on to a lot of memory, so allow
796 # them to be freed before we go into our poll wait.
6303359 Ben Darnell Fix a regression in which a timeout could fire after being cancelled.
bdarnell authored
797 callbacks = callback = due_timeouts = timeout = None
1591ade Ben Darnell Improve callback scheduling.
bdarnell authored
798
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
799 if self._callbacks:
800 # If any callbacks or timeouts called add_callback,
801 # we don't want to wait in poll() before we run them.
802 poll_timeout = 0.0
1591ade Ben Darnell Improve callback scheduling.
bdarnell authored
803 elif self._timeouts:
804 # If there are any timeouts, schedule the first one.
805 # Use self.time() instead of 'now' to account for time
806 # spent running callbacks.
807 poll_timeout = self._timeouts[0].deadline - self.time()
808 poll_timeout = max(0, min(poll_timeout, _POLL_TIMEOUT))
809 else:
810 # No timeouts and no callbacks, so use the default.
811 poll_timeout = _POLL_TIMEOUT
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
812
813 if not self._running:
814 break
815
816 if self._blocking_signal_threshold is not None:
817 # clear alarm so it doesn't fire while poll is waiting for
818 # events.
819 signal.setitimer(signal.ITIMER_REAL, 0, 0)
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
820
821 try:
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
822 event_pairs = self._impl.poll(poll_timeout)
823 except Exception as e:
824 # Depending on python version and IOLoop implementation,
825 # different exception types may be thrown and there are
826 # two ways EINTR might be signaled:
827 # * e.errno == errno.EINTR
828 # * e.args is like (errno.EINTR, 'Interrupted system call')
f81a25e Doug Goldstein define and use errno_from_exception abstraction
cardoe authored
829 if errno_from_exception(e) == errno.EINTR:
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
830 continue
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
831 else:
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
832 raise
833
834 if self._blocking_signal_threshold is not None:
835 signal.setitimer(signal.ITIMER_REAL,
836 self._blocking_signal_threshold, 0)
837
838 # Pop one fd at a time from the set of pending fds and run
839 # its handler. Since that handler may perform actions on
840 # other file descriptors, there may be reentrant calls to
841 # this IOLoop that update self._events
842 self._events.update(event_pairs)
843 while self._events:
844 fd, events = self._events.popitem()
845 try:
0416a68 Ben Darnell Pass the correct file object to IOLoop handler functions.
bdarnell authored
846 fd_obj, handler_func = self._handlers[fd]
847 handler_func(fd_obj, events)
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
848 except (OSError, IOError) as e:
f81a25e Doug Goldstein define and use errno_from_exception abstraction
cardoe authored
849 if errno_from_exception(e) == errno.EPIPE:
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
850 # Happens when the client closes the connection
851 pass
852 else:
853 self.handle_callback_exception(self._handlers.get(fd))
854 except Exception:
bfba45b Ben Darnell Route all callback error logging in IOLoop through handle_callback_excep...
bdarnell authored
855 self.handle_callback_exception(self._handlers.get(fd))
0416a68 Ben Darnell Pass the correct file object to IOLoop handler functions.
bdarnell authored
856 fd_obj = handler_func = None
7700df7 Anton Ryzhov Reset state on `start()` end
anton-ryzhov authored
857
858 finally:
859 # reset the stopped flag so another start/stop pair can be issued
860 self._stopped = False
861 if self._blocking_signal_threshold is not None:
862 signal.setitimer(signal.ITIMER_REAL, 0, 0)
863 IOLoop._current.instance = old_current
864 if old_wakeup_fd is not None:
865 signal.set_wakeup_fd(old_wakeup_fd)
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
866
867 def stop(self):
868 self._running = False
3ab6390 If IOLoop.stop is called before the loop is running, make the next
Ben Darnell authored
869 self._stopped = True
2963eed Ben Darnell Move the waker pipe into tornado.platform.
bdarnell authored
870 self._waker.wake()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
871
20deb5c Ben Darnell Add time_func parameter to IOLoop, and make it possible to use time.mono...
bdarnell authored
872 def time(self):
873 return self.time_func()
874
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
875 def call_at(self, deadline, callback, *args, **kwargs):
876 timeout = _Timeout(
877 deadline,
878 functools.partial(stack_context.wrap(callback), *args, **kwargs),
879 self)
458cc4f Ben Darnell Remove some debugging code that was accidentally committed.
bdarnell authored
880 heapq.heappush(self._timeouts, timeout)
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
881 return timeout
882
883 def remove_timeout(self, timeout):
b6c4d6d Ben Darnell Change IOLoop._timeouts from a sorted list to a heapq.
bdarnell authored
884 # Removing from a heap is complicated, so just leave the defunct
6ac8a05 Evan Klitzke improve the speed of add_callback by avoiding the waker pipe when possib...
eklitzke authored
885 # timeout object in the queue (see discussion in
b6c4d6d Ben Darnell Change IOLoop._timeouts from a sorted list to a heapq.
bdarnell authored
886 # http://docs.python.org/library/heapq.html).
887 # If this turns out to be a problem, we could add a garbage
888 # collection pass whenever there are too many dead timeouts.
889 timeout.callback = None
a6d158f Ben Darnell Clean up cancelled timeout handles when the queue gets full of them.
bdarnell authored
890 self._cancellations += 1
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
891
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
892 def add_callback(self, callback, *args, **kwargs):
2ee58f1 Ben Darnell Fix race condition in cross-thread IOLoop.add_callback
bdarnell authored
893 with self._callback_lock:
b724652 Ben Darnell Ensure that add_callback fails cleanly if called while IOLoop is closing...
bdarnell authored
894 if self._closing:
895 raise RuntimeError("IOLoop is closing")
2ee58f1 Ben Darnell Fix race condition in cross-thread IOLoop.add_callback
bdarnell authored
896 list_empty = not self._callbacks
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
897 self._callbacks.append(functools.partial(
e582e58 Ben Darnell Update autopep8 to 0.8.5 and run it.
bdarnell authored
898 stack_context.wrap(callback), *args, **kwargs))
8e7effd Ben Darnell In add_callback, hold the lock while writing to the waker pipe.
bdarnell authored
899 if list_empty and thread.get_ident() != self._thread_ident:
900 # If we're in the IOLoop's thread, we know it's not currently
901 # polling. If we're not, and we added the first callback to an
902 # empty list, we may need to wake it up (it may wake up on its
903 # own, but an occasional extra wake is harmless). Waking
904 # up a polling IOLoop is relatively expensive, so we try to
905 # avoid it when we can.
906 self._waker.wake()
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
907
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
908 def add_callback_from_signal(self, callback, *args, **kwargs):
ae7cfe4 Ben Darnell Add IOLoop.add_callback_from_signal, which avoids deadlocks
bdarnell authored
909 with stack_context.NullContext():
910 if thread.get_ident() != self._thread_ident:
911 # if the signal is handled on another thread, we can add
912 # it normally (modulo the NullContext)
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
913 self.add_callback(callback, *args, **kwargs)
ae7cfe4 Ben Darnell Add IOLoop.add_callback_from_signal, which avoids deadlocks
bdarnell authored
914 else:
915 # If we're on the IOLoop's thread, we cannot use
916 # the regular add_callback because it may deadlock on
917 # _callback_lock. Blindly insert into self._callbacks.
918 # This is safe because the GIL makes list.append atomic.
919 # One subtlety is that if the signal interrupted the
920 # _callback_lock block in IOLoop.start, we may modify
921 # either the old or new version of self._callbacks,
922 # but either way will work.
ea79e8a Ben Darnell add_callback now takes *args, **kwargs.
bdarnell authored
923 self._callbacks.append(functools.partial(
e582e58 Ben Darnell Update autopep8 to 0.8.5 and run it.
bdarnell authored
924 stack_context.wrap(callback), *args, **kwargs))
ae7cfe4 Ben Darnell Add IOLoop.add_callback_from_signal, which avoids deadlocks
bdarnell authored
925
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
926
927 class _Timeout(object):
928 """An IOLoop timeout, a UNIX timestamp and a callback"""
e340491 Add __slots__ to ioloop._Timeout to reduce memory overhead when there ar...
Ben Darnell authored
929
930 # Reduce memory overhead when there are lots of pending callbacks
5fc96e6 Drew Winstel ioloop.py: use itertools.count() as tiebreaker to preserve FIFO in case ...
drewbrew authored
931 __slots__ = ['deadline', 'callback', 'tiebreaker']
e340491 Add __slots__ to ioloop._Timeout to reduce memory overhead when there ar...
Ben Darnell authored
932
20deb5c Ben Darnell Add time_func parameter to IOLoop, and make it possible to use time.mono...
bdarnell authored
933 def __init__(self, deadline, callback, io_loop):
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
934 if not isinstance(deadline, numbers.Real):
688d59d Ben Darnell Accept timedelta objects in IOLoop.add_timeout.
bdarnell authored
935 raise TypeError("Unsupported deadline %r" % deadline)
2cec319 Ben Darnell Introduce IOLoop.call_later and call_at.
bdarnell authored
936 self.deadline = deadline
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
937 self.callback = callback
5fc96e6 Drew Winstel ioloop.py: use itertools.count() as tiebreaker to preserve FIFO in case ...
drewbrew authored
938 self.tiebreaker = next(io_loop._timeout_counter)
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
939
7c3dea7 Ben Darnell Fix for python2.5: heapq used to use __le__ instead of __lt__
bdarnell authored
940 # Comparison methods to sort by deadline, with object id as a tiebreaker
941 # to guarantee a consistent ordering. The heapq module uses __le__
942 # in python2.5, and __lt__ in 2.6+ (sort() and most other comparisons
6ac8a05 Evan Klitzke improve the speed of add_callback by avoiding the waker pipe when possib...
eklitzke authored
943 # use __lt__).
130040a Ben Darnell Python3 fixes in IOLoop
bdarnell authored
944 def __lt__(self, other):
5fc96e6 Drew Winstel ioloop.py: use itertools.count() as tiebreaker to preserve FIFO in case ...
drewbrew authored
945 return ((self.deadline, self.tiebreaker) <
946 (other.deadline, other.tiebreaker))
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
947
7c3dea7 Ben Darnell Fix for python2.5: heapq used to use __le__ instead of __lt__
bdarnell authored
948 def __le__(self, other):
5fc96e6 Drew Winstel ioloop.py: use itertools.count() as tiebreaker to preserve FIFO in case ...
drewbrew authored
949 return ((self.deadline, self.tiebreaker) <=
950 (other.deadline, other.tiebreaker))
7c3dea7 Ben Darnell Fix for python2.5: heapq used to use __le__ instead of __lt__
bdarnell authored
951
2afa973 Bret Taylor Move Tornado project to Github
finiteloop authored
952
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
953 class PeriodicCallback(object):
954 """Schedules the given callback to be called periodically.
955
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
956 The callback is called every ``callback_time`` milliseconds.
497245e Ben Darnell Expand PeriodicCallback docs and testing.
bdarnell authored
957 Note that the timeout is given in milliseconds, while most other
958 time-related functions in Tornado use seconds.
959
960 If the callback runs for longer than ``callback_time`` milliseconds,
961 subsequent invocations will be skipped to get back on schedule.
55d3be1 Ben Darnell Run coverage check and fill in the blanks
bdarnell authored
962
c11f8d0 Ben Darnell Doc updates, modules H-L
bdarnell authored
963 `start` must be called after the `PeriodicCallback` is created.
ab6b980 Ben Darnell A new IOLoop is automatically "current" if there isn't already one.
bdarnell authored
964
965 .. versionchanged:: 4.1
966 The ``io_loop`` argument is deprecated.
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
967 """
968 def __init__(self, callback, callback_time, io_loop=None):
969 self.callback = callback
317508b Peter Sobot Added more sensical callback time verification.
psobot authored
970 if callback_time <= 0:
971 raise ValueError("Periodic callback must have a positive callback_time")
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
972 self.callback_time = callback_time
2ad9659 Ben Darnell All functions that take an IOLoop default to current() instead of instan...
bdarnell authored
973 self.io_loop = io_loop or IOLoop.current()
fcab358 Ben Darnell Set PeriodicCallback._running to True in start instead of __init__
bdarnell authored
974 self._running = False
700f5a7 Justin Rosenthal Prevent duplicate callbacks when PeriodicCallback is stopped and restart...
justinrosenthal authored
975 self._timeout = None
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
976
977 def start(self):
55d3be1 Ben Darnell Run coverage check and fill in the blanks
bdarnell authored
978 """Starts the timer."""
fcab358 Ben Darnell Set PeriodicCallback._running to True in start instead of __init__
bdarnell authored
979 self._running = True
20deb5c Ben Darnell Add time_func parameter to IOLoop, and make it possible to use time.mono...
bdarnell authored
980 self._next_timeout = self.io_loop.time()
c4c5960 Jesus Arias Fisteus Stabilization of the period of ioloop.PeriodicCallback.
jfisteus authored
981 self._schedule_next()
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
982
983 def stop(self):
55d3be1 Ben Darnell Run coverage check and fill in the blanks
bdarnell authored
984 """Stops the timer."""
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
985 self._running = False
700f5a7 Justin Rosenthal Prevent duplicate callbacks when PeriodicCallback is stopped and restart...
justinrosenthal authored
986 if self._timeout is not None:
987 self.io_loop.remove_timeout(self._timeout)
988 self._timeout = None
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
989
6dc5dd9 ami_GS add is_running to get callback state
ami-GS authored
990 def is_running(self):
76f20ec Ben Darnell Document PeriodicCallback.is_running.
bdarnell authored
991 """Return True if this `.PeriodicCallback` has been started.
992
993 .. versionadded:: 4.1
994 """
6dc5dd9 ami_GS add is_running to get callback state
ami-GS authored
995 return self._running
996
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
997 def _run(self):
c152b78 Ben Darnell While I'm touching every file, run autopep8 too.
bdarnell authored
998 if not self._running:
999 return
be71a24 Bret Taylor Experimental module auto-reloading on modification
finiteloop authored
1000 try:
2d6c02a Zhicheng Wei Fix `PeriodicCallback' when callback function return `Future' and has
zhicheng authored
1001 return self.callback()
17eed4f Ben Darnell Replace all bare "except:" blocks with "except Exception:" so we don't
bdarnell authored
1002 except Exception:
bfba45b Ben Darnell Route all callback error logging in IOLoop through handle_callback_excep...
bdarnell authored
1003 self.io_loop.handle_callback_exception(self.callback)
2d6c02a Zhicheng Wei Fix `PeriodicCallback' when callback function return `Future' and has
zhicheng authored
1004 finally:
1005 self._schedule_next()
c4c5960 Jesus Arias Fisteus Stabilization of the period of ioloop.PeriodicCallback.
jfisteus authored
1006
1007 def _schedule_next(self):
9163e34 Ben Darnell Check self._running before rescheduling a PeriodicCallback, so stop() ca...
bdarnell authored
1008 if self._running:
20deb5c Ben Darnell Add time_func parameter to IOLoop, and make it possible to use time.mono...
bdarnell authored
1009 current_time = self.io_loop.time()
497245e Ben Darnell Expand PeriodicCallback docs and testing.
bdarnell authored
1010
a5e7ee7 Philipp Engel modified method _schedule_next of PeriodicCallback to handle sudden chan...
nosyjoe authored
1011 if self._next_timeout <= current_time:
1012 callback_time_sec = self.callback_time / 1000.0
1013 self._next_timeout += (math.floor((current_time - self._next_timeout) / callback_time_sec) + 1) * callback_time_sec
1014
700f5a7 Justin Rosenthal Prevent duplicate callbacks when PeriodicCallback is stopped and restart...
justinrosenthal authored
1015 self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run)
Something went wrong with that request. Please try again.