On Mar 3, 2014, at 5:07 PM, Victor Stinner <[email protected]> wrote:
> Hi, > > 2014-03-03 23:59 GMT+01:00 Nikolay Kim <[email protected]>: >> I see "InvalidStateError: CANCELLED: Future<CANCELLED>” exception in my >> production system. >> It doesn’t really affect application logic, just annoying. also it is very >> hard to understand where exception from. >> so i propose to add safe_set_result() method to Future that will check >> status before setting result. >> code review is here https://codereview.appspot.com/69870048/ > > I didn't understood with your example what happens. In fact, the > future is cancelled before future.set_result() is called. Something > like: > --- > fut = Future() > <do something else> > fut.cancel() > <do something else> > fut.set_result() > --- > where "<do something else>" is a side-effect of asynchronous > programming and "yield from”. yes, thats right. but fut.set_result is called by event loop. i see this kind of exceptions: Feb 28 00:28:03 ip-10-31-197-58 ERROR [asyncio] Exception in callback <bound method Future.set_result of Future<CANCELLED>>(None,) handle: Handle(<bound method Future.set_result of Future<CANCELLED>>, (None,)) Traceback (most recent call last): File "/usr/local/lib/python3.3/dist-packages/asyncio-0.4.1_p1-py3.3.egg/asyncio/events.py", line 39, in _run self._callback(*self._args) File "/usr/local/lib/python3.3/dist-packages/asyncio-0.4.1_p1-py3.3.egg/asyncio/futures.py", line 298, in set_result raise InvalidStateError('{}: {!r}'.format(self._state, self)) asyncio.futures.InvalidStateError: CANCELLED: Future<CANCELLED> > > Checking the future status before scheduling the call (with > loop.call_soon) to set_result() would not fix the issue. it doesn’t check status of fut before scheduling call with call_soon, it checks status of fut during set_result call. > > If I understood correctly, _SelectorSocketTransport constructor > doesn't call directly set_result() (but use loop.call_soon instead) to > wait until protocol.connection_made() has been called. So > loop.create_connection() only returns the socket when > protocol.connection_made() has been called. Is this correct? > _SelectorSocketTransport constructor cannot call directly > protocol.connection_made()? waiter future is used by clients and that’s different topic. this problem is not directly related to _SelectorSocketTransport, but how it uses Future.set_result. i can write similar test for asyncio.sleep as well.
