cpython: 7aa2d3e1c885 (original) (raw)

Mercurial > cpython

changeset 97277:7aa2d3e1c885 3.4

Issue #23812: Fix asyncio.Queue.get() to avoid loosing items on cancellation. Patch by Gustavo J. A. M. Carneiro. [#23812]

Yury Selivanov yselivanov@sprymix.com
date Wed, 05 Aug 2015 13:52:33 -0400
parents 94e215a5e24b
children d5644d7e222d ee8e9edb8aae
files Lib/asyncio/queues.py Lib/test/test_asyncio/test_queues.py Misc/NEWS
diffstat 3 files changed, 101 insertions(+), 10 deletions(-)[+] [-] Lib/asyncio/queues.py 47 Lib/test/test_asyncio/test_queues.py 61 Misc/NEWS 3

line wrap: on

line diff

--- a/Lib/asyncio/queues.py +++ b/Lib/asyncio/queues.py @@ -47,7 +47,7 @@ class Queue: # Futures. self._getters = collections.deque()

@@ -98,7 +98,7 @@ class Queue: def _consume_done_putters(self): # Delete waiters at the head of the put() queue who've timed out.

def qsize(self): @@ -148,8 +148,9 @@ class Queue: elif self._maxsize > 0 and self._maxsize <= self.qsize(): waiter = futures.Future(loop=self._loop)

else: self.__put_internal(item) @@ -186,8 +187,7 @@ class Queue: self._consume_done_putters() if self._putters: assert self.full(), 'queue not full, why are putters waiting?'

# When a getter runs and frees up a slot so this putter can # run, we need to defer the put for a tick to ensure that @@ -201,9 +201,39 @@ class Queue: return self._get() else: waiter = futures.Future(loop=self._loop)

+

+

def get_nowait(self): """Remove and return an item from the queue. @@ -213,8 +243,7 @@ class Queue: self._consume_done_putters() if self._putters: assert self.full(), 'queue not full, why are putters waiting?'

# getter cannot be cancelled, we just removed done putters

--- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -171,7 +171,7 @@ class QueueGetTests(_QueueTestBase): q.put_nowait(1) waiter = asyncio.Future(loop=self.loop)

res = self.loop.run_until_complete(q.get()) self.assertEqual(1, res) @@ -322,6 +322,64 @@ class QueuePutTests(_QueueTestBase): q.put_nowait(1) self.assertEqual(1, q.get_nowait())

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+ def test_nonblocking_put_exception(self): q = asyncio.Queue(maxsize=1, loop=self.loop) q.put_nowait(1) @@ -374,6 +432,7 @@ class QueuePutTests(_QueueTestBase): test_utils.run_briefly(self.loop) self.assertTrue(put_c.done()) self.assertEqual(q.get_nowait(), 'a')

self.loop.run_until_complete(put_b)

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -63,6 +63,9 @@ Core and Builtins