1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17  """Base classes handy for use with PB clients. 
 18  """ 
 19   
 20  from twisted.spread import pb 
 21   
 22  from twisted.spread.pb import PBClientFactory 
 23  from twisted.internet import protocol, reactor 
 24  from twisted.python import log 
 25  from twisted.cred import error 
 26   
 29      """Reconnecting client factory for PB brokers. 
 30   
 31      Like PBClientFactory, but if the connection fails or is lost, the factory 
 32      will attempt to reconnect. 
 33   
 34      Instead of using f.getRootObject (which gives a Deferred that can only 
 35      be fired once), override the gotRootObject method. 
 36   
 37      Instead of using the newcred f.login (which is also one-shot), call 
 38      f.startLogin() with the credentials and client, and override the 
 39      gotPerspective method. 
 40   
 41      gotRootObject and gotPerspective will be called each time the object is 
 42      received (once per successful connection attempt). You will probably want 
 43      to use obj.notifyOnDisconnect to find out when the connection is lost. 
 44   
 45      If an authorization error occurs, failedToGetPerspective() will be 
 46      invoked. 
 47   
 48      To use me, subclass, then hand an instance to a connector (like 
 49      TCPClient). 
 50      """ 
 51   
 52       
 53       
 54      hungConnectionTimer = None 
 55      HUNG_CONNECTION_TIMEOUT = 120 
 56   
 62   
 68   
 71   
 77   
 78       
 79   
 81          raise RuntimeError, "login is one-shot: use startLogin instead" 
  82   
 84          self._credentials = credentials 
 85          self._client = client 
  86   
 93   
 94       
 95   
102               
103          self.hungConnectionTimer = reactor.callLater(self.HUNG_CONNECTION_TIMEOUT, hungConnection) 
 104   
109   
110       
111   
113          """The remote avatar or perspective (obtained each time this factory 
114          connects) is now available.""" 
115          self.stopHungConnectionTimer() 
 116   
118          """The remote root object (obtained each time this factory connects) 
119          is now available. This method will be called each time the connection 
120          is established and the object reference is retrieved.""" 
121          self.stopHungConnectionTimer() 
 122   
124          """The login process failed, most likely because of an authorization 
125          failure (bad password), but it is also possible that we lost the new 
126          connection before we managed to send our credentials. 
127          """ 
128          log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 
129          self.stopHungConnectionTimer() 
130           
131          if why.check(pb.PBConnectionLost): 
132              log.msg("we lost the brand-new connection") 
133               
134          elif why.check(error.UnauthorizedLogin): 
135              log.msg("unauthorized login; check slave name and password") 
136               
137          else: 
138              log.err(why, 'While trying to connect:') 
139              self.stopTrying() 
140              reactor.stop() 
141              return 
142   
143           
144          broker.transport.loseConnection() 
 145