tornadoweb / tornadoweb/tornado

"tornado.curl_httpclient.CurlError: HTTP 599: Failed writing header" after updating to python 3.10 on alpine 3.15

Open
#3,091 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

httpclient investigation
Dominant language
Python
Stars
22.2k
Forks
5.6k
Avg merge
3h 42m
Merged PRs (30d)
16

Description

Hi,
Recently I've updated my tornado tests container to python:3.10-alpine3.15 from python:3.9.6-alpine3.14. After doing this, my tests started to fail with the error below.

These are my dependencies:

coverage==5.3
pytest==6.2.4
pytest-cov==2.10.1
pytest-rerunfailures==10.1
redislite==5.0.142319
pytest-mock==3.6.1
pytest-tornado==0.8.1
ptvsd==4.2.7
pytest-xdist==2.3.0
aiohttp==3.7.4.post0
SQLAlchemy==1.4.22
Deprecated==1.2.11
nest-asyncio==1.5.1
ldap3==2.7
tornado==6.1
alembic==1.6.5
psycopg2==2.9.1
asyncpg==0.23.0
pycurl==7.43.0
cookies==2.2.1
opuslib==3.0.1
redis==3.3.8
apispec==3.3.1
apispec-webframeworks==0.5.2
marshmallow==3.7.0
itsdangerous==1.1.0
sendgrid==5.6.0
grpcio-tools==1.38.1
protoc-gen-swagger==0.1.0
googleapis-common-protos==1.6.0
prometheus_client==0.7.1
jaeger-client==4.3.0
python-dateutil==2.8.1

Any idea what could cause this errors?

Thanks

tests/admin/handlers/data_collection/data_collection_test.py:233: in _create_task
    response = self._fetch(TASKS_URI, body=json.dumps(task), method='POST')
tests/base.py:608: in _fetch
    return self.fetch(*args, **kwargs)
/usr/local/lib/python3.10/site-packages/tornado/testing.py:443: in fetch
    return self.io_loop.run_sync(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <tornado.platform.asyncio.AsyncIOLoop object at 0x7f43438c2ef0>, func = <function AsyncHTTPTestCase.fetch.<locals>.<lambda> at 0x7f43437497e0>, timeout = 300.0

    def run_sync(self, func: Callable, timeout: Optional[float] = None) -> Any:
        """Starts the `IOLoop`, runs the given function, and stops the loop.
    
        The function must return either an awaitable object or
        ``None``. If the function returns an awaitable object, the
        `IOLoop` will run until the awaitable is resolved (and
        `run_sync()` will return the awaitable's result). If it raises
        an exception, the `IOLoop` will stop and the exception will be
        re-raised to the caller.
    
        The keyword-only argument ``timeout`` may be used to set
        a maximum duration for the function.  If the timeout expires,
        a `tornado.util.TimeoutError` is raised.
    
        This method is useful to allow asynchronous calls in a
        ``main()`` function::
    
            async def main():
                # do stuff...
    
            if __name__ == '__main__':
                IOLoop.current().run_sync(main)
    
        .. versionchanged:: 4.3
           Returning a non-``None``, non-awaitable value is now an error.
    
        .. versionchanged:: 5.0
           If a timeout occurs, the ``func`` coroutine will be cancelled.
    
        """
        future_cell = [None]  # type: List[Optional[Future]]
    
        def run() -> None:
            try:
                result = func()
                if result is not None:
                    from tornado.gen import convert_yielded
    
                    result = convert_yielded(result)
            except Exception:
                fut = Future()  # type: Future[Any]
                future_cell[0] = fut
                future_set_exc_info(fut, sys.exc_info())
            else:
                if is_future(result):
                    future_cell[0] = result
                else:
                    fut = Future()
                    future_cell[0] = fut
                    fut.set_result(result)
            assert future_cell[0] is not None
            self.add_future(future_cell[0], lambda future: self.stop())
    
        self.add_callback(run)
        if timeout is not None:
    
            def timeout_callback() -> None:
                # If we can cancel the future, do so and wait on it. If not,
                # Just stop the loop and return with the task still pending.
                # (If we neither cancel nor wait for the task, a warning
                # will be logged).
                assert future_cell[0] is not None
                if not future_cell[0].cancel():
                    self.stop()
    
            timeout_handle = self.add_timeout(self.time() + timeout, timeout_callback)
        self.start()
        if timeout is not None:
            self.remove_timeout(timeout_handle)
        assert future_cell[0] is not None
        if future_cell[0].cancelled() or not future_cell[0].done():
            raise TimeoutError("Operation timed out after %s seconds" % timeout)
>       return future_cell[0].result()
E       tornado.curl_httpclient.CurlError: HTTP 599: Failed writing header

/usr/local/lib/python3.10/site-packages/tornado/ioloop.py:530: CurlError

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure from tests/admin/handlers/data_collection/data_collection_test.py:233 via tests/base.py:608 using the listed Python 3.10 Alpine 3.15 dependencies, then compare with the Python 3.9 Alpine 3.14 image. Trace Tornado's AsyncHTTPTestCase.fetch through the curl client and pycurl; done means the cause is identified and the affected test suite passes on the supported setup.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.