viff

changeset 832:dc276dba4113

Handle CannotListenError gracefully. Instead of crashing if our port is already in use, we now try again after an exponentially increasing back off period. This closes Issue 6.
author Martin Geisler <mg@daimi.au.dk>
date Mon, 14 Jul 2008 00:24:21 +0200
parents 889882a2798b
children b8aa2d01692d
files viff/runtime.py
diffstat 1 files changed, 17 insertions(+), 2 deletions(-) [+]
line diff
     1.1 --- a/viff/runtime.py	Sun Jul 13 23:58:53 2008 +0200
     1.2 +++ b/viff/runtime.py	Mon Jul 14 00:24:21 2008 +0200
     1.3 @@ -33,6 +33,7 @@
     1.4  
     1.5  __docformat__ = "restructuredtext"
     1.6  
     1.7 +import time
     1.8  import marshal
     1.9  from optparse import OptionParser, OptionGroup
    1.10  from math import ceil
    1.11 @@ -45,7 +46,7 @@
    1.12  from viff.util import wrapper, rand
    1.13  
    1.14  from twisted.internet import reactor
    1.15 -from twisted.internet.error import ConnectionDone
    1.16 +from twisted.internet.error import ConnectionDone, CannotListenError
    1.17  from twisted.internet.defer import Deferred, DeferredList, gatherResults, succeed
    1.18  from twisted.internet.defer import maybeDeferred
    1.19  from twisted.internet.protocol import ReconnectingClientFactory, ServerFactory
    1.20 @@ -1541,7 +1542,21 @@
    1.21          listen = lambda port: reactor.listenTCP(port, factory)
    1.22          connect = lambda host, port: reactor.connectTCP(host, port, factory)
    1.23  
    1.24 -    runtime.port = listen(players[id].port)
    1.25 +    port = players[id].port
    1.26 +    runtime.port = None
    1.27 +    delay = 2
    1.28 +    while runtime.port is None:
    1.29 +        # We keep trying to listen on the port, but with an
    1.30 +        # exponentially increasing delay between each attempt.
    1.31 +        try:
    1.32 +            runtime.port = listen(port)
    1.33 +        except CannotListenError, e:
    1.34 +            delay *= 1 + rand.random()
    1.35 +            print "Error listening on port %d: %s" % (port, e.socketError[1])
    1.36 +            print "Will try again in %d seconds" % delay
    1.37 +            time.sleep(delay)
    1.38 +    print "Listening on port %d" % port
    1.39 +
    1.40      for peer_id, player in players.iteritems():
    1.41          if peer_id > id:
    1.42              print "Will connect to %s" % player