Skip to content

Commit

Permalink
core/select: add {Select,Latch,Receiver}.size(), deprecate empty()
Browse files Browse the repository at this point in the history
Knowing an estimate of the buffered items is needed for adding a
latch/receiver with many existing buffered items via Select.add().
  • Loading branch information
dw committed Aug 8, 2019
1 parent 95b067a commit 49a6446
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 25 deletions.
64 changes: 48 additions & 16 deletions mitogen/core.py
Expand Up @@ -1095,13 +1095,32 @@ def close(self):
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()

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -2385,19 +2407,17 @@ def close(self):
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.
Expand All @@ -2406,10 +2426,22 @@ def empty(self):
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.
Expand Down
26 changes: 17 additions & 9 deletions mitogen/select.py
Expand Up @@ -259,18 +259,26 @@ def close(self):
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()

Expand Down

0 comments on commit 49a6446

Please sign in to comment.