Add docs for undocumented functions and modules.
--- /dev/null
+``tornado.concurrent`` --- Work with threads and futures
+========================================================
+
+.. automodule:: tornado.concurrent
+ :members:
.. automethod:: IOLoop.instance
.. automethod:: IOLoop.initialized
.. automethod:: IOLoop.install
+ .. automethod:: IOLoop.current
+ .. automethod:: IOLoop.make_current
.. automethod:: IOLoop.start
.. automethod:: IOLoop.stop
.. automethod:: IOLoop.run_sync
iostream
httpclient
netutil
+ tcpserver
~~~~~~~~~~~~~~~~~~~
* Client-side WebSocket support is now available:
- `tornado.websocket.WebSocketConnect`
+ `tornado.websocket.websocket_connect`
* `WebSocketHandler` has new methods `ping` and `on_pong` to send pings
to the browser (not supported on the ``draft76`` protocol)
--- /dev/null
+``tornado.tcpserver`` --- Basic `IOStream`-based TCP server
+===========================================================
+
+.. automodule:: tornado.tcpserver
+ :members:
.. toctree::
autoreload
+ concurrent
gen
httputil
log
.. automethod:: WebSocketHandler.async_callback
.. automethod:: WebSocketHandler.ping
.. automethod:: WebSocketHandler.on_pong
+
+
+ Client-side support
+ -------------------
+
+ .. autofunction:: websocket_connect
+ .. autoclass:: WebSocketClientConnection
+ :members:
def run_on_executor(fn):
+ """Decorator to run a synchronous method asynchronously on an executor.
+
+ The decorated method may be called with a ``callback`` keyword
+ argument and returns a future.
+ """
@functools.wraps(fn)
def wrapper(self, *args, **kwargs):
callback = kwargs.pop("callback", None)
`gen.engine` function, or passing it to `IOLoop.add_future`).
Usage::
+
@return_future
def future_func(arg1, arg2, callback):
# Do stuff (possibly asynchronous)
self._close_callback = None
def set_close_callback(self, callback):
+ """Sets a callback that will be run when the connection is closed.
+
+ Use this instead of accessing `HTTPConnection.stream.set_close_callback`
+ directly (which was the recommended approach prior to Tornado 3.0).
+ """
self._close_callback = stack_context.wrap(callback)
self.stream.set_close_callback(self._on_connection_close)
@staticmethod
def current():
+ """Returns the current thread's `IOLoop`.
+
+ If an `IOLoop` is currently running or has been marked as current
+ by `make_current`, returns that instance. Otherwise returns
+ `IOLoop.instance()`, i.e. the main thread's `IOLoop`.
+
+ In general you should use `IOLoop.current` as the default when
+ constructing an asynchronous object, and use `IOLoop.instance`
+ when you mean to communicate to the main thread from a different
+ one.
+ """
current = getattr(IOLoop._current, "instance", None)
if current is None:
return IOLoop.instance()
return current
def make_current(self):
+ """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` explictly before starting the `IOLoop`,
+ so that code run at startup time can find the right
+ instance.
+ """
IOLoop._current.instance = self
@staticmethod
class Resolver(Configurable):
+ """Configurable asynchronous DNS resolver interface.
+
+ By default, a blocking implementation is used (which simply
+ calls `socket.getaddrinfo`). An alternative implementation
+ can be chosen with the `Resolver.configure` class method::
+
+ Resolver.configure('tornado.netutil.ThreadedResolver')
+
+ The implementations of this interface included with Tornado are
+
+ * `tornado.netutil.BlockingResolver`
+ * `tornado.netutil.ThreadedResolver`
+ * `tornado.netutil.OverrideResolver`
+ * `tornado.platform.twisted.TwistedResolver`
+ * `tornado.platform.caresresolver.CaresResolver`
+ """
@classmethod
def configurable_base(cls):
return Resolver
class BlockingResolver(ExecutorResolver):
+ """Default `Resolver` implementation, using `socket.getaddrinfo`.
+
+ The `IOLoop` will be blocked during the resolution, although the
+ callback will not be run until the next `IOLoop` iteration.
+ """
def initialize(self, io_loop=None):
super(BlockingResolver, self).initialize(io_loop=io_loop)
class ThreadedResolver(ExecutorResolver):
+ """Multithreaded non-blocking `Resolver` implementation.
+
+ Requires the `concurrent.futures` package to be installed
+ (available in the standard library since Python 3.2,
+ installable with ``pip install futures`` in older versions).
+
+ The thread pool size can be configured with::
+
+ Resolver.configure('tornado.netutil.ThreadedResolver',
+ num_threads=10)
+ """
def initialize(self, io_loop=None, num_threads=10):
from concurrent.futures import ThreadPoolExecutor
super(ThreadedResolver, self).initialize(
from tornado.testing import AsyncHTTPTestCase, gen_test
from tornado.web import Application
-from tornado.websocket import WebSocketHandler, WebSocketConnect
+from tornado.websocket import WebSocketHandler, websocket_connect
class EchoHandler(WebSocketHandler):
@gen_test
def test_websocket_gen(self):
- ws = yield WebSocketConnect(
+ ws = yield websocket_connect(
'ws://localhost:%d/echo' % self.get_http_port(),
io_loop=self.io_loop)
ws.write_message('hello')
self.assertEqual(response, 'hello')
def test_websocket_callbacks(self):
- WebSocketConnect(
+ websocket_connect(
'ws://localhost:%d/echo' % self.get_http_port(),
io_loop=self.io_loop, callback=self.stop)
ws = self.wait().result()
self.stream.io_loop.time() + 5, self._abort)
-class _WebSocketClientConnection(simple_httpclient._HTTPConnection):
+class WebSocketClientConnection(simple_httpclient._HTTPConnection):
+ """WebSocket client connection."""
def __init__(self, io_loop, request):
self.connect_future = Future()
self.read_future = None
'Sec-WebSocket-Version': '13',
})
- super(_WebSocketClientConnection, self).__init__(
+ super(WebSocketClientConnection, self).__init__(
io_loop, None, request, lambda: None, lambda response: None,
104857600, Resolver(io_loop=io_loop))
self.connect_future.set_result(self)
def write_message(self, message, binary=False):
+ """Sends a message to the WebSocket server."""
self.protocol.write_message(message, binary)
def read_message(self, callback=None):
+ """Reads a message from the WebSocket server.
+
+ Returns a future whose result is the message, or None
+ if the connection is closed. If a callback argument
+ is given it will be called with the future when it is
+ ready.
+ """
assert self.read_future is None
future = Future()
if self.read_queue:
pass
-def WebSocketConnect(url, io_loop=None, callback=None):
+def websocket_connect(url, io_loop=None, callback=None):
+ """Client-side websocket support.
+
+ Takes a url and returns a Future whose result is a `WebSocketConnection`.
+ """
if io_loop is None:
io_loop = IOLoop.current()
request = httpclient.HTTPRequest(url)
request = httpclient._RequestProxy(
request, httpclient.HTTPRequest._DEFAULTS)
- conn = _WebSocketClientConnection(io_loop, request)
+ conn = WebSocketClientConnection(io_loop, request)
if callback is not None:
io_loop.add_future(conn.connect_future, callback)
return conn.connect_future