bakwc / PySyncObj

A library for replicating your python class between multiple servers, based on raft protocol
MIT License
706 stars 113 forks source link

TypeError: inet_aton() when the address cannot be resolved #142

Closed bofm closed 3 years ago

bofm commented 3 years ago

When the addresses cannot be resolved, an unhandled error is raised.

>>> SyncObj('a:1', ['b:1'])
WARNING:root:failed to resolve host a
WARNING:root:failed to resolve host b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/x/.virtualenvs/x-X6HqzFbE/lib/python3.8/site-packages/pysyncobj/syncobj.py", line 197, in __init__
    self.__transport = transportClass(self, self.__selfNode, self.__otherNodes)
  File "/Users/x/.virtualenvs/x-X6HqzFbE/lib/python3.8/site-packages/pysyncobj/transport.py", line 208, in __init__
    self._createServer()
  File "/Users/x/.virtualenvs/x-X6HqzFbE/lib/python3.8/site-packages/pysyncobj/transport.py", line 251, in _createServer
    self._server = TcpServer(self._syncObj._poller, host, port, onNewConnection = self._onNewIncomingConnection,
  File "/Users/x/.virtualenvs/x-X6HqzFbE/lib/python3.8/site-packages/pysyncobj/tcp_server.py", line 19, in __init__
    self.__hostAddrType = _getAddrType(host)
  File "/Users/x/.virtualenvs/x-X6HqzFbE/lib/python3.8/site-packages/pysyncobj/tcp_connection.py", line 20, in _getAddrType
    socket.inet_aton(addr)
TypeError: inet_aton() argument 1 must be str, not None
ghost commented 3 years ago

I ran into this same problem today as well. My application runs in Kubernetes where the hostname wont resolve while things are recovering.

2021-07-28 04:01:10 WARNING  failed to resolve host do-ip-bouncer-0.do-ip-bouncer

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/threading.py", line 973, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/syncobj.py", line 520, in _autoTickThread
    self._onTick(self.__conf.autoTickPeriod)
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/syncobj.py", line 614, in _onTick
    callback()
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/transport.py", line 302, in _onTick
    self._connectIfNecessary()
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/transport.py", line 423, in _connectIfNecessary
    self._connectIfNecessarySingle(node)
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/transport.py", line 415, in _connectIfNecessarySingle
    return self._connections[node].connect(node.ip, node.port)
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/tcp_connection.py", line 76, in connect
    self.__socket = socket.socket(_getAddrType(host), socket.SOCK_STREAM)
  File "/usr/local/lib/python3.9/site-packages/pysyncobj/tcp_connection.py", line 20, in _getAddrType
    socket.inet_aton(addr)
TypeError: inet_aton() argument 1 must be str, not None
bakwc commented 3 years ago

You expect that it should retry until hostname resolution starts working?

ghost commented 3 years ago

Yeah, in cloud environments DNS is typically treated as a pliable resource. In Kubernetes clusters, DNS caching is the worst thing an application can do.

This package could be very useful in cloud native applications with some changes to how DNS is handled.

bakwc commented 3 years ago

Uploaded fix to master (#152), could you try it and let me know if helped? To avoid DNS caching - set SyncObjConf option dnsCacheTime to 5 (seconds)

ghost commented 3 years ago

Here's how I did validation on this, with test resources: https://gist.github.com/protosam/80a68e9e8c75ba2cb1e5a08f86d6b7f1

It works great.

Thanks for the patch.