Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ghevge opened this issue Dec 13, 2021 · 1 comment

Comments

@ghevge
Copy link

ghevge commented Dec 13, 2021

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

@bdarnell
Copy link
Member

I have no idea what might be causing this, but I noticed nest-asyncio in your dependencies list, and I'm suspicious of that package. Nesting asyncio event loops in the wrong places could cause all kinds of undefined behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants