From f1881e8a4360e835f0921d056cb58e4d2cac7423 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 19 Dec 2012 19:35:42 -0800 Subject: [PATCH] Small tweaks and clarifications. --- pep-3156.txt | 75 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/pep-3156.txt b/pep-3156.txt index 31b11a348..cc981e6e3 100644 --- a/pep-3156.txt +++ b/pep-3156.txt @@ -148,66 +148,69 @@ loop per thread. Event Loop Interface -------------------- -A conforming event loop object has the following methods: +(A note about times: as usual in Python, all timeouts, intervals and +delays are measured in seconds, and may be ints or floats. The +accuracy and precision of the clock are up to the implementation; the +default implementation uses ``time.monotonic()``.) -.. - Look for a better way to format method docs. PEP 12 doesn't seem to - have one. PEP 418 uses ^^^, which makes sub-headings. PEP 3148 - 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. +A conforming event loop object has the following methods: - ``run()``. Runs the event loop until there is nothing left to do. This means, in particular: - - No more calls scheduled with ``call_later()`` (except for canceled - calls). + - No more calls scheduled with ``call_later()``, + ``call_repeatedly()``, ``call_soon()``, or + ``call_soon_threadsafe()``, except for canceled calls. - No more registered file descriptors. It is up to the registering party to unregister a file descriptor when it is closed. - Note: run() blocks until the termination condition is met. + Note: ``run()`` blocks until the termination condition is met, + or until ``stop()`` is called. + + Note: if you schedule a call with ``call_repeatedly()``, ``run()`` + will not exit until you cancel it. - ``stop()``. Stops the event loop as soon as it is convenient. It is fine to restart the loop with ``run()`` (or one of its variants) - subsequently. (TBD: How should this interact with ``run_once()`` - and ``run_until_complete()``?) + subsequently. - Note: How soon exactly is up to the implementation. It is - reasonable to implement this so that ``run()`` simply stops calling - ``run_once()`` when this is called. + Note: How soon exactly is up to the implementation. All immediate + callbacks that were already scheduled to run before ``stop()`` is + called must still be run, but callbacks scheduled after it is called + (or scheduled to be run later) will not be run. - ``run_until_complete(future, timeout=None)``. Runs the event loop - until a Future is done. If a timeout is given, it waits at most + until the Future is done. If a timeout is given, it waits at most that long. If the Future is done, its result is returned, or its exception is raised; if the timeout expires before the Future is - done, TimeoutError is raised (but the Future is not cancelled). - This cannot be called when the event loop is already running. + done, or if ``stop()`` is called, ``TimeoutError`` is raised (but + the Future is not cancelled). This cannot be called when the event + loop is already running. Note: This API is most useful for tests and the like. It should not be used as a substitute for ``yield from future`` or other ways to wait for a Future (e.g. registering a done callback). - ``run_once(timeout=None)``. Run the event loop for a little while. - If a timeout is given, an I/O poll will be given at most that timeout; - otherwise, an I/O poll is not constrained in time. + If a timeout is given, an I/O poll made will block at most that + long; otherwise, an I/O poll is not constrained in time. - Note: Exactlly what this does is up to the implementation. One - constraint: if a callback immediately schedules itself using - ``call_soon()``, ``run_once()`` should still return. + Note: Exactlly how much work this does is up to the implementation. + One constraint: if a callback immediately schedules itself using + ``call_soon()``, causing an infinite loop, ``run_once()`` should + still return. - ``call_later(delay, callback, *args)``. Arrange for ``callback(*args)`` to be called approximately ``delay`` seconds in - the future, once, unless canceled. As usual in Python, ``delay`` may - be a floating point number to represent smaller intervals. Returns + the future, once, unless canceled. Returns a ``Handler`` object representing the callback, whose ``cancel()`` method can be used to cancel the callback. - ``call_repeatedly(interval, callback, **args)``. Like ``call_later()`` but calls the callback repeatedly, every ``interval`` seconds, until the ``Handler`` returned is cancelled. The first call is in - ``interval`` seconds. May be a float. + ``interval`` seconds. - ``call_soon(callback, *args)``. Equivalent to ``call_later(0, callback, *args)``. @@ -225,8 +228,6 @@ A conforming event loop object has the following methods: ``isinstance(callback, Handler)``? It should silently skip a canceled callback. -- TBD: Repeatable timers. - Some methods in the standard conforming interface return Futures: - ``wrap_future(future)``. This takes a PEP 3148 Future (i.e., an @@ -336,10 +337,8 @@ i.e. no disk files. TBD: What about multiple callbacks per fd? The current semantics is that ``add_reader()/add_writer()`` replace a previously registered -callback. - -TBD: Should ``remove_*()`` return a bool telling is whether it removed -anything? +callback. Change this to raise an exception if a callback is already +registered. The following methods for doing async I/O on sockets are optional. They are alternative to the previous set of optional methods, intended @@ -353,7 +352,8 @@ supports it). The socket argument has to be a non-blocking socket. - ``sock_sendall(sock, data)``. Send bytes ``data`` to the socket ``sock``. Returns a Future whose result on success will be ``None``. (TBD: Is it better to emulate ``sendall()`` or ``send()`` - semantics?) + semantics? I think ``sendall()`` -- but perhaps it should still + be *named* ``send()``?) - ``sock_connect(sock, address)``. Connect to the given address. Returns a Future whose result on success will be ``None``. @@ -605,9 +605,10 @@ Transports have the following public methods: TBD: Provide flow control the other way -- the transport may need to suspend the protocol if the amount of data buffered becomes a burden. -One option: let the transport call ``protocol.pause()`` and -``protocol.resume()`` if they exist; if they don't exist, the protocol -doesn't support flow control. +Proposal: let the transport call ``protocol.pause()`` and +``protocol.resume()`` if they exist; if they don't exist, the +protocol doesn't support flow control. (Perhaps different names +to avoid confusion between protocols and transports?) Protocols ---------