I have seen a similar behavior with aioredis:

See my message here: 
https://groups.google.com/forum/#!topic/python-tulip/_J6BedIpu5I

Le vendredi 3 avril 2015 17:17:08 UTC+2, Victor Stinner a écrit :
>
> Hum, I didn't get any reply to this message :-( I opened an issue to 
> at least document the behaviour: 
> https://bugs.python.org/issue23859 
>
> By the way, while discussing with Natim on IRC, we found a bug in the 
> websockets project which uses wait() on a queue.get() task. If the 
> wait() is cancelled, you can loose an item of the queue if the get 
> task is not called. See my fix: 
>
> diff --git a/websockets/protocol.py b/websockets/protocol.py 
> index 7e4a94e..5353b74 100644 
> --- a/websockets/protocol.py 
> +++ b/websockets/protocol.py 
> @@ -166,9 +166,13 @@ class 
> WebSocketCommonProtocol(asyncio.StreamReaderProtocol): 
>
>          # Wait for a message until the connection is closed 
>          next_message = asyncio.async(self.messages.get(), 
> loop=self._loop) 
> -        done, pending = yield from asyncio.wait( 
> -                [next_message, self.worker], 
> -                loop=self._loop, return_when=asyncio.FIRST_COMPLETED) 
> +        try: 
> +            done, pending = yield from asyncio.wait( 
> +                    [next_message, self.worker], 
> +                    loop=self._loop, return_when=asyncio.FIRST_COMPLETED) 
> +        except: 
> +            next_message.cancel() 
> +            raise 
>          if next_message in done: 
>              return next_message.result() 
>          else: 
>
> The full recv() method: 
>
> https://github.com/aaugustin/websockets/blob/7d8191699a6d647c1b45e3e11681c5987437e5b5/websockets/protocol.py#L149
>  
>
> Victor 
>
> 2015-01-29 10:06 GMT+01:00 Victor Stinner <[email protected] 
> <javascript:>>: 
> > Hi, 
> > 
> > While I tried to write a example cancelling create_connection(), I saw 
> > that asynico.wait() doesn't cancel waited tasks when it is cancelled. 
> > 
> > In the following example, the result of fut is never used, so asyncio 
> > emits a warning (exception never retrieved): 
> > --- 
> > import asyncio 
> > 
> > def func(): 
> >     fut = asyncio.Future() 
> >     fs = [fut] 
> >     fut2 = loop.create_task(asyncio.wait(fs)) 
> >     fut2.cancel() 
> >     fut.set_exception(ValueError("never catched")) 
> >     try: 
> >         yield from fut2 
> >     except asyncio.CancelledError: 
> >         pass 
> >     # nobody cares of fut result? 
> > 
> > loop = asyncio.get_event_loop() 
> > loop.run_until_complete(func()) 
> > loop.close() 
> > --- 
> > 
> > Is it correct that wait() doesn't cancel waited tasks? 
> > 
> > wait_for() was modified recently to cancel the waited task when 
> > wait_for() is cancelled: 
> > http://bugs.python.org/issue23219 
> > 
> > asyncio.gather() does cancel tasks when it is cancelled: 
> > https://docs.python.org/dev/library/asyncio-task.html#asyncio.gather 
> > 
> > If wait() must not cancel tasks, it should be better explained in the 
> > documentation and asyncio code should be audited to ensure that tasks 
> > are explicitly cancelled. 
> > 
> > For example, replace: 
> > 
> >     yield from tasks.wait(fs, loop=self) 
> > 
> > with: 
> > 
> >     try: 
> >         yield from tasks.wait(fs, loop=self) 
> >     except CancelledError: 
> >         for fut in fs: 
> >             fut.cancel() 
> > 
> > I only found one method calling wait(): create_connection(). 
> > 
> > Victor 
>

Reply via email to