Various Tulip updates.

This commit is contained in:
Guido van Rossum 2013-10-18 09:35:37 -07:00
parent 7dfb6b0960
commit 0e2e677032
1 changed files with 53 additions and 33 deletions

View File

@ -198,7 +198,8 @@ It is expected that ``get_event_loop()`` returns a different event
loop object depending on the context (in fact, this is the definition loop object depending on the context (in fact, this is the definition
of context). It may create a new event loop object if none is set and of context). It may create a new event loop object if none is set and
creation is allowed by the policy. The default policy will create a creation is allowed by the policy. The default policy will create a
new event loop only in the main thread, and only if new event loop only in the main thread (as defined by threading.py,
which uses a special subclass for the main thread), and only if
``get_event_loop()`` is called before ``set_event_loop()`` is ever ``get_event_loop()`` is called before ``set_event_loop()`` is ever
called. (To reset this state, reset the policy.) In other threads an called. (To reset this state, reset the policy.) In other threads an
event loop must be explicitly set. Other policies may behave event loop must be explicitly set. Other policies may behave
@ -233,11 +234,10 @@ implementations, and serves primarily as documentation. The following
concrete classes are defined: concrete classes are defined:
- ``SelectorEventLoop`` is a concrete implementation of the full API - ``SelectorEventLoop`` is a concrete implementation of the full API
based on the ``selectors`` module. (This module is part of Tulip, based on the ``selectors`` module (new in Python 3.4). The
but not specified by this PEP. It is separately proposed for constructor takes one optional argument, a ``selectors.Selector``
inclusion in the standard library.) The constructor takes one object. By default an instance of ``selectors.DefaultSelector`` is
optional argument, a ``selectors.Selector`` object. By default an created and used.
instance of ``selectors.DefaultSelector`` is created and used.
- ``ProactorEventLoop`` is a concrete implementation of the API except - ``ProactorEventLoop`` is a concrete implementation of the API except
for the I/O event handling and signal handling methods. It is only for the I/O event handling and signal handling methods. It is only
@ -485,7 +485,7 @@ Note that the client and server side of stream connections use the
same transport and protocol interface. However, datagram endpoints same transport and protocol interface. However, datagram endpoints
use a different transport and protocol interface. use a different transport and protocol interface.
- ``create_connection(protocol_factory, host, port, **kwargs)``. - ``create_connection(protocol_factory, host, port, <options>)``.
Creates a stream connection to a given internet host and port. This Creates a stream connection to a given internet host and port. This
is a task that is typically called from the client side of the is a task that is typically called from the client side of the
connection. It creates an implementation-dependent (bidirectional connection. It creates an implementation-dependent (bidirectional
@ -507,11 +507,23 @@ use a different transport and protocol interface.
You can also pass a trivial ``lambda`` that returns a previously You can also pass a trivial ``lambda`` that returns a previously
constructed Protocol instance. constructed Protocol instance.
Optional keyword arguments: The <options> are all specified using optional keyword arguments:
- ``ssl``: Pass ``True`` to create an SSL transport (by default a - ``ssl``: Pass ``True`` to create an SSL transport (by default a
plain TCP transport is created). Or pass an ``ssl.SSLContext`` plain TCP transport is created). Or pass an ``ssl.SSLContext``
object to override the default SSL context object to be used. object to override the default SSL context object to be used. If
a default context is created it is up to the implementation to
configure reasonable defaults. The reference implementation
currently uses ``PROTOCOL_SSLv23`` and sets the ``OP_NO_SSLv2``
option, calls ``set_default_verify_paths()`` and sets verify_mode
to ``CERT_REQUIRED``. In addition, whenever the context (default
or otherwise) specifies a verify_mode of ``CERT_REQUIRED``, if a
hostname is given, immediately after a successful handshake
``ss.ssl.match_hostname(peercert, hostname)`` is called, and if
this raises an exception the conection is closed. (To avoid this
behavior, pass in an context that doesn't have verify_mode set to
``CERT_REQUIRED``. But this means you are not secure, and
vulnerable to for example man-in-the-middle attacks.)
- ``family``, ``proto``, ``flags``: Address family, protocol and - ``family``, ``proto``, ``flags``: Address family, protocol and
flags to be passed through to ``getaddrinfo()``. These all flags to be passed through to ``getaddrinfo()``. These all
@ -532,13 +544,15 @@ use a different transport and protocol interface.
specific address. This is how you would do that. The host and specific address. This is how you would do that. The host and
port are looked up using ``getaddrinfo()``. port are looked up using ``getaddrinfo()``.
- ``start_serving(protocol_factory, host, port, **kwds)``. Enters a - ``create_server_serving(protocol_factory, host, port,
serving loop that accepts connections. This is a coroutine that <options>)``. Enters a serving loop that accepts connections.
completes once the serving loop is set up to serve. The return This is a coroutine that completes once the serving loop is set up
value is a list of one or more sockets in listening mode. (Multiple to serve. The return value is a ``Server`` object which can be used
sockets may be returned if the specified address allows both IPv4 to stop the serving loop in a controlled fashion by calling its
and IPv6 connections.) You can use ``stop_serving()`` to stop the ``close()`` method.
serving loop. Each time a connection is accepted,
Multiple sockets may be bound if the specified address allows
both IPv4 and IPv6 connections. Each time a connection is accepted,
``protocol_factory`` is called without arguments(*) to create a ``protocol_factory`` is called without arguments(*) to create a
Protocol, a (bidirectional stream) Transport is created to represent Protocol, a (bidirectional stream) Transport is created to represent
the network side of the connection, and the two are tied together by the network side of the connection, and the two are tied together by
@ -549,7 +563,7 @@ use a different transport and protocol interface.
connection, it should return a new Protocol object each time it is connection, it should return a new Protocol object each time it is
called. called.
Optional keyword arguments: The <options> are all specified using optional keyword arguments:
- ``ssl``: Pass an ``ssl.SSLContext`` object to override the default - ``ssl``: Pass an ``ssl.SSLContext`` object to override the default
SSL context object to be used. (Unlike ``create_connection()``, SSL context object to be used. (Unlike ``create_connection()``,
@ -583,8 +597,8 @@ use a different transport and protocol interface.
return a list of opaque objects that can be passed to return a list of opaque objects that can be passed to
``stop_serving()``.) ``stop_serving()``.)
- ``create_datagram_endpoint(protocol_factory, local_addr, - ``create_datagram_endpoint(protocol_factory, local_addr=None,
remote_addr, **kwds)``. Creates an endpoint for sending and remote_addr=None, **kwds)``. Creates an endpoint for sending and
receiving datagrams (typically UDP packets). Because of the nature receiving datagrams (typically UDP packets). Because of the nature
of datagram traffic, there are no separate calls to set up client of datagram traffic, there are no separate calls to set up client
and server side, since usually a single endpoint acts as both client and server side, since usually a single endpoint acts as both client
@ -1027,12 +1041,12 @@ Bidirectional stream transports have the following public methods:
is known ahead of time, the best approach in both cases is to use is known ahead of time, the best approach in both cases is to use
the Content-Length header.) the Content-Length header.)
- ``pause()``. Suspend delivery of data to the protocol until a - ``pause_reading()``. Suspend delivery of data to the protocol until
subsequent ``resume()`` call. Between ``pause()`` and ``resume()``, a subsequent ``resume_reading()`` call. Between ``pause_reading()``
the protocol's ``data_received()`` method will not be called. This and ``resume_reading()``, the protocol's ``data_received()`` method
has no effect on ``write()``. will not be called. This has no effect on ``write()``.
- ``resume()``. Restart delivery of data to the protocol via - ``resume_reading()``. Restart delivery of data to the protocol via
``data_received()``. ``data_received()``.
- ``close()``. Sever the connection with the entity at the other end. - ``close()``. Sever the connection with the entity at the other end.
@ -1053,8 +1067,8 @@ Bidirectional stream transports have the following public methods:
TBD: Provide flow control the other way -- the transport may need to TBD: Provide flow control the other way -- the transport may need to
suspend the protocol if the amount of data buffered becomes a burden. suspend the protocol if the amount of data buffered becomes a burden.
Proposal: let the transport call ``protocol.pause()`` and Proposal: let the transport call ``protocol.pause_writing()`` and
``protocol.resume()`` if they exist; if they don't exist, the ``protocol.resume_writing()`` if they exist; if they don't exist, the
protocol doesn't support flow control. (Perhaps different names protocol doesn't support flow control. (Perhaps different names
to avoid confusion between protocols and transports?) to avoid confusion between protocols and transports?)
@ -1065,8 +1079,9 @@ A writing stream transport supports the ``write()``, ``writelines()``,
``write_eof()``, ``can_write_eof()``, close() and ``abort()`` methods ``write_eof()``, ``can_write_eof()``, close() and ``abort()`` methods
described for bidrectional stream transports. described for bidrectional stream transports.
A reading stream transport supports the ``pause()``, ``resume()`` and A reading stream transport supports the ``pause_reading()``,
``close()`` methods described for bidrectional stream transports. ``resume_reading()`` and ``close()`` methods described for
bidrectional stream transports.
A writing stream transport calls only ``connection_made()`` and A writing stream transport calls only ``connection_made()`` and
``connection_lost()`` on its associated protocol. ``connection_lost()`` on its associated protocol.
@ -1146,9 +1161,11 @@ context. (See the "Context" section way above.)
p.data_received(b'def') p.data_received(b'def')
- ``eof_received()``. This is called when the other end called - ``eof_received()``. This is called when the other end called
``write_eof()`` (or something equivalent). The default ``write_eof()`` (or something equivalent). If this returns a false
implementation calls ``close()`` on the transport, which causes value (including None), the transport will close itself. If it
``connection_lost()`` to be called (eventually) on the protocol. returns a true value, closing the transport is up to the protocol.
The default implementation returns None.
- ``connection_lost(exc)``. The transport has been closed or aborted, - ``connection_lost(exc)``. The transport has been closed or aborted,
has detected that the other end has closed the connection cleanly, has detected that the other end has closed the connection cleanly,
@ -1412,6 +1429,9 @@ off the coroutine when ``connection_made()`` is called.
Open Issues Open Issues
=========== ===========
- Make ``loop.stop()`` optional (and hence
``loop.run_until_complete()`` too).
- A fuller public API for Handle? What's the use case? - A fuller public API for Handle? What's the use case?
- Should we require all event loops to implement ``sock_recv()`` and - Should we require all event loops to implement ``sock_recv()`` and
@ -1434,8 +1454,8 @@ Open Issues
- Locks and queues? The Tulip implementation contains implementations - Locks and queues? The Tulip implementation contains implementations
of most types of locks and queues modeled after the standard library of most types of locks and queues modeled after the standard library
``threading`` and ``queue`` modules. Should we incorporate these in ``threading`` and ``queue`` modules. These should be incorporated
the PEP? into the PEP.
- Probably need more socket I/O methods, e.g. ``sock_sendto()`` and - Probably need more socket I/O methods, e.g. ``sock_sendto()`` and
``sock_recvfrom()``, and perhaps others like ``pipe_read()``. Or ``sock_recvfrom()``, and perhaps others like ``pipe_read()``. Or