Oh sorry... No it didn't solve my problem. The assertions all pass and the error messages remain. I also added logging as you recommended, but it only shows that the exception is None.
On Friday, March 28, 2014 12:16:26 AM UTC+1, Guido van Rossum wrote: > > So does this solve your problem or not? You didn't say... > > > On Thu, Mar 27, 2014 at 4:15 PM, Florian Rüchel > <[email protected]<javascript:> > > wrote: > >> I modified the code a little, so I make sure it is done and has no >> exception: >> >> def done(fut): >> print("Future is done") >> for task in conn_tasks: >> task.add_done_callback(done) >> done, pending = yield from asyncio.wait(conn_tasks, timeout=5) >> assert not pending >> for task in done: >> assert task.exception() is None >> assert task.result() is None >> >> This executes cleanly, without throwing an exception and prints "Future >> is done" for each connection. >> >> On Friday, March 28, 2014 12:07:41 AM UTC+1, Guido van Rossum wrote: >> >>> Looks to me like you're never asking for the result of those Futures >>> you're passing to asyncio.wait(). It waits until the Futures are complete, >>> but it doesn't inspect whether they have errors. You need something like >>> >>> for task in done: >>> if task.exception(): ...log it... >>> >>> >>> On Thu, Mar 27, 2014 at 3:19 PM, Florian Rüchel <[email protected]>wrote: >>> >>>> I can post the code, I just thought it might be too much. However, I'll >>>> just post the relevant section. Contrary to multithreaded programming here >>>> most of the times the local section is enough (I love asyncio :)) >>>> >>>> Anyways here is the main function: >>>> >>>> try: >>>> self.event_loop.run_forever() >>>> except KeyboardInterrupt: >>>> exit_main_loop() >>>> finally: >>>> print("Running shutdown cleanup") >>>> collector.cancel() >>>> >>>> @asyncio.coroutine >>>> def shutdown(): >>>> yield from self.connection_pool.close() >>>> self.event_loop.run_until_complete(shutdown()) >>>> self.event_loop.close() >>>> >>>> And the close method: >>>> >>>> @asyncio.coroutine >>>> def close(self): >>>> try: >>>> if self.returned_connections: >>>> msg = ("Not all connections were returned: %s" >>>> % self.returned_connections) >>>> log.error(msg) >>>> raise ValueError(msg) >>>> finally: >>>> conn_tasks = [asyncio.Task(conn.disconnect()) >>>> for conn in self.all_connections] >>>> done, pending = yield from asyncio.wait(conn_tasks, timeout=5) >>>> assert not pending >>>> >>>> Relevant is the finally part: I wrap each connection in a task and wait >>>> for them together. Removing the timeout did not help (I didn't expect it >>>> would, no exception is raised). >>>> >>>> Per existing connection (up to 10) a message is produced: >>>> >>>> 2014-03-27 23:11:58,143 ERROR[asyncio] Coroutine 'disconnect' defined >>>> at /path/to/library/connection.py:109 was never yielded from >>>> >>>> I have made sure that the amount of logging messages matches exactly >>>> the number of connections created (by counting the logging messages inside >>>> connection's __init__ function). In a very simple case there was only one >>>> connection, so only one error entry and only one log entry for a created >>>> connection. >>>> >>>> Hope this additional information helps uncover the issue. Thanks for >>>> the response. >>>> >>>> On Thursday, March 27, 2014 10:23:10 AM UTC+1, Florian Rüchel wrote: >>>>> >>>>> Hi everyone, >>>>> >>>>> I currently have a problem I cannot figure out. My code is running >>>>> perfectly fine, but when using "PYTHONASYNCIODEBUG=1" it reports that a >>>>> function was never yielded from per instance of that class I have. The >>>>> problem is I cannot create an example that replicates the issue and the >>>>> application is fairly large so maybe someone can give a hint on where I >>>>> might go looking. The function in question is a method of a connection >>>>> class. The class manages a TCP connection that has to send an init and a >>>>> disconnect request. It is the disconnect method that is reported as never >>>>> yielded from. I have log entries that prove that this function was >>>>> actually >>>>> run and I have tried wrapping it in asyncio.Task and asyncio.async and I >>>>> also had a wrapping coroutine that *was *called and an explicit >>>>> "yield from connection.disconnect()" statement. >>>>> >>>>> In all three cases the proper log entries were written and the server >>>>> got the disconnect request, so I know it was properly executed. Now I am >>>>> wondering if I have a bug in my application that is hidden somewhere >>>>> between the layers that is repsonsible for this message. Or is it >>>>> possible >>>>> to trigger this error message even though the function was properly >>>>> called? >>>>> >>>>> I'd also like to note that this is *the only* method where this >>>>> happens, all other methods on all other classes are never reported as >>>>> problematic.I have checked the method against others but I cannot find >>>>> any >>>>> difference at all: They are called with yield from or as tasks, they all >>>>> use other coroutines (the connect and disconnect method actually both use >>>>> *yield >>>>> from self.talk(...)*) and they are all properly decorated. >>>>> >>>>> I'm sorry I cannot provide any code examples, but since I am unable to >>>>> replicate the issue in a small sample, I fear I need further guidance on >>>>> where to look for the issue. >>>>> >>>>> Many thanks in advance and Regards, >>>>> Florian >>>>> >>>> >>> >>> >>> -- >>> --Guido van Rossum (python.org/~guido) >>> >> > > > -- > --Guido van Rossum (python.org/~guido) >
