Skip to content

Commit

Permalink
Don't triplicate connection attempts
Browse files Browse the repository at this point in the history
The loop over all possible IPv4 and IPv6 addresses turns out to also
loop through all possible socket types (SOCK_STREAM/IPPROTO_TCP,
SOCK_DGRAM/IPPROTO_UDP, SOCK_RAW/IPPROTO_IP).  This meant that each
connection attempt was repeated three times, serially.

This fixes new_addr.test nondeterministic failures.  Here's a short
reminder of what that test does:

  1. Starts a ZEO server on random port X
  2. Connects and creates some data
  3. Stops the ZEO server
  4. Starts a new ZEO server on random port Y
  5. Tells the old connection about the new address
  6. Makes a modification though a new connection
  7. Waits for the old connection to reconnect using the new address,
  8. Verifies that it sees the new data

Here's why the test used to fail:

  * In step 3, when we stop the ZEO server, the client would notice a
    disconnect and immediately try to reconnect.

  * Due to this bug it would open three TCP connections to localhost:X
    and somehow succeed (I've no idea why -- ZEO server is supposed to
    close the listening socket before it drops client connections, so
    how can a new connection to the listening socket succeed?)

  * It would try handshaking each of the connection one after the other,
    timing out after 10 seconds each time (in ZEO.ServerStub.stub).

  * Only after all three connection attempts failed would it sleep for
    `max_disconnect_poll` seconds and then try to connect to localhost:Y

  * Three times 10 seconds is 30 seconds, which is by accident the same
    timeout the test uses in step 7 to wait for a successful
    reconnection.

With this fix the test still does one unnecessary 10 second timeout
before it passes.  I'd love to fix it, but I'm losing hope of
understanding what's actually happening there.
  • Loading branch information
mgedmin committed May 27, 2013
1 parent 4b44eed commit c293082
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/ZEO/tests/new_addr.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ We'll start by setting up a server and connecting to it:
... ('127.0.0.1', 0), {'1': ZODB.FileStorage.FileStorage('t.fs')})
>>> server.start_thread()

>>> conn = ZEO.connection(server.addr)
>>> conn = ZEO.connection(server.addr, max_disconnect_poll=0.1)
>>> client = conn.db().storage
>>> client.is_connected()
True
Expand Down
5 changes: 5 additions & 0 deletions src/ZEO/zrpc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,11 @@ def _expand_addrlist(self):
host, port = addr
for (family, socktype, proto, cannoname, sockaddr
) in socket.getaddrinfo(host or 'localhost', port):
# we only speak TCP, so let's skip UDP and RAW sockets
# otherwise we'll try to connect to the same address
# three times in a row
if socktype != socket.SOCK_STREAM:
continue
# for IPv6, drop flowinfo, and restrict addresses
# to [host]:port
yield family, sockaddr[:2]
Expand Down

0 comments on commit c293082

Please sign in to comment.