Specify Futures. Minor cleanup.
This commit is contained in:
parent
56159e8da3
commit
c0a378f775
111
pep-3156.txt
111
pep-3156.txt
|
@ -145,9 +145,12 @@ Event Loop Interface
|
||||||
A conforming event loop object has the following methods:
|
A conforming event loop object has the following methods:
|
||||||
|
|
||||||
..
|
..
|
||||||
Look for a better way to format method docs. PEP 12 doesn't
|
Look for a better way to format method docs. PEP 12 doesn't seem to
|
||||||
seem to have one. PEP 418 uses ^^^, which makes sub-headings.
|
have one. PEP 418 uses ^^^, which makes sub-headings. PEP 3148
|
||||||
Also think of adding subheadings.
|
uses a markup which generates rather heavy layout using blockquote,
|
||||||
|
causing a blank line between each method heading and its
|
||||||
|
description. Also think of adding subheadings for different
|
||||||
|
categories of methods.
|
||||||
|
|
||||||
- ``run()``. Runs the event loop until there is nothing left to do.
|
- ``run()``. Runs the event loop until there is nothing left to do.
|
||||||
This means, in particular:
|
This means, in particular:
|
||||||
|
@ -183,11 +186,16 @@ A conforming event loop object has the following methods:
|
||||||
later time in a threadsafe manner, you can use
|
later time in a threadsafe manner, you can use
|
||||||
``ev.call_soon_threadsafe(ev.call_later, when, callback, *args)``.)
|
``ev.call_soon_threadsafe(ev.call_later, when, callback, *args)``.)
|
||||||
|
|
||||||
|
- TBD: A way to register a callback that is already wrapped in a
|
||||||
|
``DelayedCall``. Maybe ``call_soon()`` could just check
|
||||||
|
``isinstance(callback, DelayedCall)``? It should silently skip
|
||||||
|
a canceled callback.
|
||||||
|
|
||||||
Some methods return Futures:
|
Some methods return Futures:
|
||||||
|
|
||||||
- ``wrap_future(future)``. This takes a PEP 3148 Future (i.e., an
|
- ``wrap_future(future)``. This takes a PEP 3148 Future (i.e., an
|
||||||
instance of ``concurrent.futures.Future``) and returns a Future
|
instance of ``concurrent.futures.Future``) and returns a Future
|
||||||
compatible with this event loop.
|
compatible with the event loop (i.e., a ``tulip.Future`` instance).
|
||||||
|
|
||||||
- ``run_in_executor(executor, function, *args)``. Arrange to call
|
- ``run_in_executor(executor, function, *args)``. Arrange to call
|
||||||
``function(*args)`` in an executor (see PEP 3148). Returns a Future
|
``function(*args)`` in an executor (see PEP 3148). Returns a Future
|
||||||
|
@ -263,30 +271,24 @@ for transport implementations on Windows using IOCP (if the event loop
|
||||||
supports it). The socket argument has to be a non-blocking socket.
|
supports it). The socket argument has to be a non-blocking socket.
|
||||||
|
|
||||||
- ``sock_recv(sock, n)``. Receive up to ``n`` bytes from socket
|
- ``sock_recv(sock, n)``. Receive up to ``n`` bytes from socket
|
||||||
``sock``. Returns a ``Future`` whose result on success will be a
|
``sock``. Returns a Future whose result on success will be a
|
||||||
bytes object on success.
|
bytes object on success.
|
||||||
|
|
||||||
- ``sock_sendall(sock, data)``. Send bytes ``data`` to the socket
|
- ``sock_sendall(sock, data)``. Send bytes ``data`` to the socket
|
||||||
``sock``. Returns a ``Future`` whose result on success will be
|
``sock``. Returns a Future whose result on success will be
|
||||||
``None``. (TBD: Is it better to emulate ``sendall()`` or ``send()``
|
``None``. (TBD: Is it better to emulate ``sendall()`` or ``send()``
|
||||||
semantics?)
|
semantics?)
|
||||||
|
|
||||||
- ``sock_connect(sock, address)``. Connect to the given address.
|
- ``sock_connect(sock, address)``. Connect to the given address.
|
||||||
Returns a ``Future`` whose result on success will be ``None``.
|
Returns a Future whose result on success will be ``None``.
|
||||||
|
|
||||||
- ``sock_accept(sock)``. Accept a connection from a socket. The
|
- ``sock_accept(sock)``. Accept a connection from a socket. The
|
||||||
socket must be in listening mode and bound to an address. Returns a
|
socket must be in listening mode and bound to an address. Returns a
|
||||||
``Future`` whose result on success will be a tuple ``(conn, peer)``
|
Future whose result on success will be a tuple ``(conn, peer)``
|
||||||
where ``conn`` is a connected non-blocking socket and ``peer`` is
|
where ``conn`` is a connected non-blocking socket and ``peer`` is
|
||||||
the peer address. (TBD: People tell me that this style of API is
|
the peer address. (TBD: People tell me that this style of API is
|
||||||
too slow for high-volume servers. So there's also
|
too slow for high-volume servers. So there's also
|
||||||
``start_serving()`` above.)
|
``start_serving()`` above. Then do we still need this?)
|
||||||
|
|
||||||
Other TBD:
|
|
||||||
|
|
||||||
- TBD: Do we need introspection APIs? E.g. asking for the read
|
|
||||||
callback given a file descriptor. Or when the next scheduled call
|
|
||||||
is. Or the list of file descriptors registered with callbacks.
|
|
||||||
|
|
||||||
Callback Sequencing
|
Callback Sequencing
|
||||||
-------------------
|
-------------------
|
||||||
|
@ -320,15 +322,76 @@ in the same event loop.
|
||||||
The DelayedCall Class
|
The DelayedCall Class
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
TBD. (Only one method, ``cancel()``, and a read-only property,
|
The various methods for registering callbacks (e.g. ``call_later()``)
|
||||||
``canceled``. Perhaps also ``callback`` and ``args`` properties.)
|
all return an object representing the registration that can be used to
|
||||||
|
cancel the callback. For want of a better name this object is called
|
||||||
|
a ``DelayedCall``, although the user never needs to instantiate
|
||||||
|
instances of this class. There is one public method:
|
||||||
|
|
||||||
TBD: Find a better name?
|
- ``cancel()``. Attempt to cancel the callback.
|
||||||
|
|
||||||
|
Read-only public attributes:
|
||||||
|
|
||||||
|
- ``callback``. The callback function to be called.
|
||||||
|
|
||||||
|
- ``args``. The argument tuple with which to call the callback function.
|
||||||
|
|
||||||
|
- ``canceled``. True if ``cancel()`` has been called.
|
||||||
|
|
||||||
|
Note that some callbacks (e.g. those registered with ``call_later()``)
|
||||||
|
are meant to be called only once. Others (e.g. those registered with
|
||||||
|
``add_reader()``) are meant to be called multiple times.
|
||||||
|
|
||||||
|
TBD: An API to call the callback (encapsulating the exception handling
|
||||||
|
necessary)? Should it record how many times it has been called?
|
||||||
|
Maybe this API should just be ``__call__()``? (But it should suppress
|
||||||
|
exceptions.)
|
||||||
|
|
||||||
|
TBD: Public attribute recording the realtime value when the callback
|
||||||
|
is scheduled? (Since this is needed anyway for storing it in a heap.)
|
||||||
|
|
||||||
|
TBD: A better name for the class?
|
||||||
|
|
||||||
Futures
|
Futures
|
||||||
-------
|
-------
|
||||||
|
|
||||||
TBD.
|
The ``tulip.Future`` class here is intentionally similar to the
|
||||||
|
``concurrent.futures.Future`` class specified by PEP 3148, but there
|
||||||
|
are slight differences. The supported public API is as follows,
|
||||||
|
indicating the differences with PEP 3148:
|
||||||
|
|
||||||
|
- ``cancel()``.
|
||||||
|
|
||||||
|
- ``cancelled()``.
|
||||||
|
|
||||||
|
- ``running()``. Note that the meaning of this method is essentially
|
||||||
|
"cannot be cancelled and isn't done yet".
|
||||||
|
|
||||||
|
- ``done()``.
|
||||||
|
|
||||||
|
- ``result()``. Difference with PEP 3148: This has no timeout
|
||||||
|
argument and does *not* wait; if the future is not yet done, it
|
||||||
|
raises an exception.
|
||||||
|
|
||||||
|
- ``exception()``. Difference with PEP 3148: This has no timeout
|
||||||
|
argument and does *not* wait; if the future is not yet done, it
|
||||||
|
raises an exception.
|
||||||
|
|
||||||
|
- ``add_done_callback(fn)``. Difference with PEP 3148: The callback
|
||||||
|
is never called immediately, and always in the context of the
|
||||||
|
caller. (Typically, a context is a thread.) You can think of this
|
||||||
|
as calling the callback through ``call_soon_threadsafe()``. Note
|
||||||
|
that the callback (unlike all other callbacks defined in this PEP)
|
||||||
|
is always called with a single argument, the Future object.
|
||||||
|
|
||||||
|
The internal methods defined in PEP 3148 are not supported.
|
||||||
|
|
||||||
|
A ``tulip.Future`` object is not acceptable to the ``wait()`` and
|
||||||
|
``as_completed()`` functions in the ``concurrent.futures`` package.
|
||||||
|
|
||||||
|
A ``tulip.Future`` object is acceptable to a yield-from expression
|
||||||
|
when used in a coroutine. See the section "Coroutines and the
|
||||||
|
Scheduler" below.
|
||||||
|
|
||||||
Transports
|
Transports
|
||||||
----------
|
----------
|
||||||
|
@ -375,6 +438,16 @@ policy.)
|
||||||
Open Issues
|
Open Issues
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
- How to spell the past tense of 'cancel'? American usage prefers
|
||||||
|
(though not absolutely dictates) 'canceled' (one ell), but outside
|
||||||
|
the US 'cancelled' (two ells) prevails. PEP 3148, whose author
|
||||||
|
currently lives in Australia, uses ``cancelled()`` as a method name
|
||||||
|
on its Future class.
|
||||||
|
|
||||||
|
- Do we need introspection APIs? E.g. asking for the read callback
|
||||||
|
given a file descriptor. Or when the next scheduled call is. Or
|
||||||
|
the list of file descriptors registered with callbacks.
|
||||||
|
|
||||||
- Should we have ``future.add_callback(callback, *args)``, using the
|
- Should we have ``future.add_callback(callback, *args)``, using the
|
||||||
convention from the section "Callback Style" above, or should we
|
convention from the section "Callback Style" above, or should we
|
||||||
stick with the PEP 3148 specification of
|
stick with the PEP 3148 specification of
|
||||||
|
|
Loading…
Reference in New Issue