M-o-a-T / moat-mqtt

An async MQTT broker and client, plus DistKV integration
MIT License
21 stars 9 forks source link

AttributeError: 'TLSStream' object has no attribute 'close' #11

Closed mikenerone closed 3 years ago

mikenerone commented 3 years ago

Stack trace says it all. Note that this is during a (trio) cancellation of the scope in which the client is running - i.e. I am intentionally shutting down this client, but not the whole app (oddly, I don't see this error when shutting down the whole app).

Traceback (most recent call last):
  File "/Users/mikenerone/dev/work/app/src/mymodule/transport.py", line 174, in _receive_packages
    del package
  File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/trio/_abc.py", line 261, in __aexit__
    await self.aclose()
  File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/trio/_channel.py", line 386, in aclose
    await trio.lowlevel.checkpoint()
  File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/trio/_core/_run.py", line 2325, in checkpoint
    await _core.wait_task_rescheduled(lambda _: _core.Abort.SUCCEEDED)
  File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/trio/_core/_traps.py", line 166, in wait_task_rescheduled
    return (await _async_yield(WaitTaskRescheduled(abort_func))).unwrap()
  File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/outcome/_impl.py", line 138, in unwrap
    raise captured_error
  File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/trio/_core/_run.py", line 1172, in raise_cancel
    raise Cancelled._create()
trio.Cancelled: Cancelled

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/distmqtt/adapters.py", line 129, in close
  await self._stream.close()
AttributeError: 'TLSStream' object has no attribute 'close'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/anyio/streams/tls.py", line 99, in _call_sslobject_method
  result = func(*args)
File "/Users/mikenerone/.pyenv/versions/3.8.6/Python.framework/Versions/3.8/lib/python3.8/ssl.py", line 948, in unwrap
  return self._sslobj.shutdown()
ssl.SSLSyscallError: Some I/O error occurred (_ssl.c:2746)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/Users/mikenerone/dev/work/app/src/mymodule/service.py", line 47, in run_service
  nursery.start_soon(partial(self.service, *args, **kwargs))
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/trio/_core/_run.py", line 815, in __aexit__
  raise combined_error_from_nursery
File "/Users/mikenerone/dev/work/app/src/mymodule/transport.py", line 148, in service
  nursery.start_soon(self._receive_packages)
File "/Users/mikenerone/dev/work/app/src/mymodule/opendxl.py", line 105, in __aexit__
  await self._client.__aexit__(exc_type, exc_val, exc_tb)
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/asyncdxlclient/client.py", line 111, in __aexit__
  await self.disconnect()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/asyncdxlclient/client.py", line 139, in disconnect
  await self._mqtt.disconnect()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/distmqtt/client.py", line 266, in disconnect
  await self._handler.stop()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/distmqtt/mqtt/protocol/client_handler.py", line 31, in stop
  await super().stop()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/distmqtt/mqtt/protocol/handler.py", line 180, in stop
  await self.stream.close()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/distmqtt/adapters.py", line 131, in close
  await self._stream.aclose()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/anyio/streams/tls.py", line 141, in aclose
  await self.unwrap()
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/anyio/streams/tls.py", line 133, in unwrap
  await self._call_sslobject_method(self._ssl_object.unwrap)
File "/Users/mikenerone/Library/Caches/pypoetry/virtualenvs/app-7FgPpmjV-py3.8/lib/python3.8/site-packages/anyio/streams/tls.py", line 118, in _call_sslobject_method
  raise BrokenResourceError from exc
anyio.BrokenResourceError

That self._stream is an anyio.streams.tls.TLSStream object. Since anyio 2.0.0, close() is renamed to aclose(). It seems likely that other updates are needed, as well (bunch of renames/deprecations at https://anyio.readthedocs.io/en/latest/versionhistory.html), but I'm just reporting the specific issue I hit.

smurfix commented 3 years ago

Umm, this particular error does get caught:

    async def close(self):
        try:
            await self._stream.close()
        except AttributeError:
            await self._stream.aclose()

Could you replace the code in distmqtt/adapters,py with

    async def close(self):
        try:
            await self._stream.aclose()
        except anyio.BrokenResourceError:
            pass

and check whether anything else breaks?

mikenerone commented 3 years ago

nm, this was my bad. I missed that there was a new release with this fixed.