From 49a6446af8777afb7da0bf5bbd20556085509f97 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Thu, 8 Aug 2019 10:45:18 +0000 Subject: [PATCH] core/select: add {Select,Latch,Receiver}.size(), deprecate empty() Knowing an estimate of the buffered items is needed for adding a latch/receiver with many existing buffered items via Select.add(). --- mitogen/core.py | 64 +++++++++++++++++++++++++++++++++++------------ mitogen/select.py | 26 ++++++++++++------- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/mitogen/core.py b/mitogen/core.py index 1fb222c6..9ef3bb02 100644 --- a/mitogen/core.py +++ b/mitogen/core.py @@ -1095,13 +1095,32 @@ class Receiver(object): self.handle = None self._latch.close() + def size(self): + """ + Return the number of items currently buffered. + + As with :class:`Queue.Queue`, `0` may be returned even though a + subsequent call to :meth:`get` will succeed, since a message may be + posted at any moment between :meth:`size` and :meth:`get`. + + As with :class:`Queue.Queue`, `>0` may be returned even though a + subsequent call to :meth:`get` will block, since another waiting thread + may be woken at any moment between :meth:`size` and :meth:`get`. + + :raises LatchError: + The underlying latch has already been marked closed. + """ + return self._latch.size() + def empty(self): """ - Return :data:`True` if calling :meth:`get` would block. + Return `size() == 0`. + + .. deprecated:: 0.2.8 + Use :meth:`size` instead. - As with :class:`Queue.Queue`, :data:`True` may be returned even though - a subsequent call to :meth:`get` will succeed, since a message may be - posted at any moment between :meth:`empty` and :meth:`get`. + :raises LatchError: + The latch has already been marked closed. """ return self._latch.empty() @@ -1150,7 +1169,10 @@ class Channel(Sender, Receiver): A channel inherits from :class:`mitogen.core.Sender` and `mitogen.core.Receiver` to provide bidirectional functionality. - This class is incomplete and obsolete, it will be removed in Mitogen 0.3. + .. deprecated:: 0.2.0 + This class is incomplete and obsolete, it will be removed in Mitogen + 0.3. + Channels were an early attempt at syntax sugar. It is always easier to pass around unidirectional pairs of senders/receivers, even though the syntax is baroque: @@ -2385,19 +2407,17 @@ class Latch(object): finally: self._lock.release() - def empty(self): + def size(self): """ - Return :data:`True` if calling :meth:`get` would block. + Return the number of items currently buffered. - As with :class:`Queue.Queue`, :data:`True` may be returned even - though a subsequent call to :meth:`get` will succeed, since a - message may be posted at any moment between :meth:`empty` and - :meth:`get`. + As with :class:`Queue.Queue`, `0` may be returned even though a + subsequent call to :meth:`get` will succeed, since a message may be + posted at any moment between :meth:`size` and :meth:`get`. - As with :class:`Queue.Queue`, :data:`False` may be returned even - though a subsequent call to :meth:`get` will block, since another - waiting thread may be woken at any moment between :meth:`empty` and - :meth:`get`. + As with :class:`Queue.Queue`, `>0` may be returned even though a + subsequent call to :meth:`get` will block, since another waiting thread + may be woken at any moment between :meth:`size` and :meth:`get`. :raises LatchError: The latch has already been marked closed. @@ -2406,10 +2426,22 @@ class Latch(object): try: if self.closed: raise LatchError() - return len(self._queue) == 0 + return len(self._queue) finally: self._lock.release() + def empty(self): + """ + Return `size() == 0`. + + .. deprecated:: 0.2.8 + Use :meth:`size` instead. + + :raises LatchError: + The latch has already been marked closed. + """ + return self.size() == 0 + def _get_socketpair(self): """ Return an unused socketpair, creating one if none exist. diff --git a/mitogen/select.py b/mitogen/select.py index ca3c32bc..f03fdae1 100644 --- a/mitogen/select.py +++ b/mitogen/select.py @@ -259,18 +259,26 @@ class Select(object): self.remove(recv) self._latch.close() - def empty(self): + def size(self): + """ + Return the number of items currently buffered. + + As with :class:`Queue.Queue`, `0` may be returned even though a + subsequent call to :meth:`get` will succeed, since a message may be + posted at any moment between :meth:`size` and :meth:`get`. + + As with :class:`Queue.Queue`, `>0` may be returned even though a + subsequent call to :meth:`get` will block, since another waiting thread + may be woken at any moment between :meth:`size` and :meth:`get`. """ - Return :data:`True` if calling :meth:`get` would block. + return sum(recv.size() for recv in self._receivers) - As with :class:`Queue.Queue`, :data:`True` may be returned even though - a subsequent call to :meth:`get` will succeed, since a message may be - posted at any moment between :meth:`empty` and :meth:`get`. + def empty(self): + """ + Return `size() == 0`. - :meth:`empty` may return :data:`False` even when :meth:`get` would - block if another thread has drained a receiver added to this select. - This can be avoided by only consuming each receiver from a single - thread. + .. deprecated:: 0.2.8 + Use :meth:`size` instead. """ return self._latch.empty()