This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ryder.lewis
Recipients ryder.lewis
Date 2014-05-06.18:28:17
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1399400899.35.0.6772968076.issue21447@psf.upfronthosting.co.za>
In-reply-to
Content
Intermittently, when using asyncio.wait_for() with asyncio.open_connection() to cancel the open_connection() task after a timeout period, an asyncio.futures.InvalidStateError is raised. It seems to be a race condition, if the open_connection() call succeeds roughly at the same time as the timeout.

In order to recreate this issue, I used a slightly-modified version of the example at https://docs.python.org/3.4/library/asyncio-stream.html?highlight=open_connection#example

==== example.py ====
import asyncio
import urllib.parse
import sys

@asyncio.coroutine
def print_http_headers(url, timeout):
    url = urllib.parse.urlsplit(url)
    try:
        reader, writer = yield from asyncio.wait_for(asyncio.open_connection(url.hostname, 80), timeout)
    except asyncio.TimeoutError:
        print('Timed out with {}-second timeout'.format(timeout))
        return

    query = ('HEAD {url.path} HTTP/1.0\r\n'
             'Host: {url.hostname}\r\n'
             '\r\n').format(url=url)
    writer.write(query.encode('latin-1'))
    while True:
        line = yield from reader.readline()
        if not line:
            break
        line = line.decode('latin1').rstrip()
        if line:
            print('HTTP header> %s' % line)

    print('Success with {}-second timeout'.format(timeout))

url = sys.argv[1]
loop = asyncio.get_event_loop()

for timeout in range(5, 0, -1):
    task = asyncio.async(print_http_headers(url, timeout/100))
    loop.run_until_complete(task)

loop.close()


==== Output of "./example.py http://www.yahoo.com/" after running multiple times ====
HTTP header> HTTP/1.0 301 Redirect
HTTP header> Date: Tue, 06 May 2014 18:07:43 GMT
HTTP header> Connection: close
HTTP header> Via: http/1.1 ir12.fp.ne1.yahoo.com (ApacheTrafficServer/4.0.2)
HTTP header> Server: ATS
HTTP header> Cache-Control: no-store
HTTP header> Content-Type: text/html; charset=utf-8
HTTP header> Content-Language: en
HTTP header> Location: https://www.yahoo.com/
HTTP header> Content-Length: 214
Success with 0.04-second timeout
Timed out with 0.03-second timeout
Timed out with 0.02-second timeout
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 "/opt/python3/lib/python3.4/asyncio/events.py", line 39, in _run
    self._callback(*self._args)
  File "/opt/python3/lib/python3.4/asyncio/futures.py", line 298, in set_result
    raise InvalidStateError('{}: {!r}'.format(self._state, self))
asyncio.futures.InvalidStateError: CANCELLED: Future<CANCELLED>
Timed out with 0.01-second timeout
History
Date User Action Args
2014-05-06 18:28:19ryder.lewissetrecipients: + ryder.lewis
2014-05-06 18:28:19ryder.lewissetmessageid: <1399400899.35.0.6772968076.issue21447@psf.upfronthosting.co.za>
2014-05-06 18:28:19ryder.lewislinkissue21447 messages
2014-05-06 18:28:17ryder.lewiscreate