(original) (raw)

changeset: 4870:26947623fc5d user: Guido van Rossum guido@python.org date: Thu May 02 14:11:08 2013 -0700 files: pep-3156.txt description: Add time(), call_at(). Remove call_repeatedly(). Get rid of add_*_handler() return value. diff -r f924a0a3da3b -r 26947623fc5d pep-3156.txt --- a/pep-3156.txt Thu May 02 05:51:33 2013 -0700 +++ b/pep-3156.txt Thu May 02 14:11:08 2013 -0700 @@ -252,13 +252,12 @@ implementation may choose not to implement the internet/socket methods, and still conform to the other methods.) -- Resource management: ``close()``. +- Miscellaneous: ``close()``, ``time()``. - Starting and stopping: ``run_forever()``, ``run_until_complete()``, ``stop()``, ``is_running()``. -- Basic callbacks: ``call_soon()``, ``call_later()``, - ``call_repeatedly()``. +- Basic callbacks: ``call_soon()``, ``call_later()``, ``call_at()``. - Thread interaction: ``call_soon_threadsafe()``, ``wrap_future()``, ``run_in_executor()``, @@ -303,8 +302,8 @@ Required Event Loop Methods --------------------------- -Resource Management -''''''''''''''''''' +Miscellaneous +''''''''''''' - ``close()``. Closes the event loop, releasing any resources it may hold, such as the file descriptor used by ``epoll()`` or @@ -313,6 +312,12 @@ again. It may be called multiple times; subsequent calls are no-ops. +- ``time()``. Returns the current time according to the event loop's + clock. This may be ``time.time()`` or ``time.monotonic()`` or some + other system-specific clock, but it must return a float expressing + the time in units of approximately one second since some epoch. + (No clock is perfect -- see PEP 418.) + Starting and Stopping ''''''''''''''''''''' @@ -362,17 +367,27 @@ ``callback(*args)`` to be called approximately ``delay`` seconds in the future, once, unless cancelled. Returns a Handle representing the callback, whose ``cancel()`` method can be used to cancel the - callback. If ``delay`` is <= 0, this acts like ``call_soon()`` - instead. Otherwise, callbacks scheduled for exactly the same time - will be called in an undefined order. + callback. Callbacks scheduled in the past or at exactly the same + time will be called in an undefined order. + +- ``call_at(when, callback, *args)``. This is like ``call_later()``, + but the time is expressed as an absolute time. There is a simple + equivalency: ``loop.call_later(delay, callback, *args)`` is the same + as ``loop.call_at(loop.time() + delay, callback, *args)``. -- ``call_repeatedly(interval, callback, **args)``. Like - ``call_later()`` but calls the callback repeatedly, every (approximately) - ``interval`` seconds, until the Handle returned is cancelled or - the callback raises an exception. The first call is in - approximately ``interval`` seconds. If for whatever reason the - callback happens later than scheduled, subsequent callbacks will be - delayed for (at least) the same amount. The ``interval`` must be > 0. +Note: A previous version of this PEP defined a method named +``call_repeatedly()``, which promised to call a callback at regular +intervals. This has been withdrawn because the design of such a +function is overspecified. On the one hand, a simple timer loop can +easily be emulated using a callback that reschedules itself using +``call_later()``; it is also easy to write coroutine containing a loop +and a ``sleep()`` call (a toplevel function in the module, see below). +On the other hand, due to the complexities of accurate timekeeping +there are many traps and pitfalls here for the unaware (see PEP 418), +and different use cases require different behavior in edge cases. It +is impossible to offer an API for this purpose that is bullet-proof in +all cases, so it is deemed better to let application designers decide +for themselves what kind of timer loop to implement. Thread interaction '''''''''''''''''' @@ -656,12 +671,9 @@ - ``add_reader(fd, callback, *args)``. Arrange for ``callback(*args)`` to be called whenever file descriptor ``fd`` is - deemed ready for reading. Returns a Handle object which can be used - to cancel the callback. (However, it is strongly preferred to use - ``remove_reader()`` instead.) Calling ``add_reader()`` again for - the same file descriptor implies a call to ``remove_reader()`` for - the same file descriptor. (TBD: Since cancelling the Handle is not - recommended, perhaps we should return None instead?) + deemed ready for reading. Calling ``add_reader()`` again for the + same file descriptor implies a call to ``remove_reader()`` for the + same file descriptor. - ``add_writer(fd, callback, *args)``. Like ``add_reader()``, but registers the callback for writing instead of for reading. @@ -669,8 +681,7 @@ - ``remove_reader(fd)``. Cancels the current read callback for file descriptor ``fd``, if one is set. If no callback is currently set for the file descriptor, this is a no-op and returns ``False``. - Otherwise, it removes the callback arrangement, cancels the - corresponding Handle, and returns ``True``. + Otherwise, it removes the callback arrangement and returns ``True``. - ``remove_writer(fd)``. This is to ``add_writer()`` as ``remove_reader()`` is to ``add_reader()``. @@ -704,11 +715,7 @@ '''''''''''''''' - ``add_signal_handler(sig, callback, *args). Whenever signal ``sig`` - is received, arrange for ``callback(*args)`` to be called. Returns - a Handle which can be used to cancel the signal callback. - (Cancelling the handle causes ``remove_signal_handler()`` to be - called the next time the signal arrives. Explicitly calling - ``remove_signal_handler()`` is preferred.) + is received, arrange for ``callback(*args)`` to be called. Specifying another callback for the same signal replaces the previous handler (only one handler can be active per signal). The ``sig`` must be a valid sigal number defined in the ``signal`` @@ -777,11 +784,12 @@ Handles ------- -The various methods for registering callbacks (e.g. ``call_soon()`` -and ``add_reader()``) all return an object representing the -registration that can be used to cancel the callback. This object is -called a Handle (although its class name is not necessarily -``Handle``). Handles are opaque and have only one public method: +The various methods for registering one-off callbacks +(``call_soon()``, ``call_later()`` and ``call_at()``) all return an +object representing the registration that can be used to cancel the +callback. This object is called a Handle (although its class name is +not necessarily ``Handle``). Handles are opaque and have only one +public method: - ``cancel()``. Cancel the callback. @@ -1354,10 +1362,6 @@ Open Issues =========== -- A ``time()`` method that returns the time according to the function - used by the scheduler (e.g. ``time.monotonic()`` in Tulip's case)? - 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 @@ -1410,6 +1414,8 @@ - PEP 3153, while rejected, has a good write-up explaining the need to separate transports and protocols. +- PEP 418 discusses the issues of timekeeping. + - Tulip repo: http://code.google.com/p/tulip/ - Nick Coghlan wrote a nice blog post with some background, thoughts /guido@python.org