Package buildslave :: Module pbutil
[frames] | no frames]

Source Code for Module buildslave.pbutil

  1   
  2  """Base classes handy for use with PB clients. 
  3  """ 
  4   
  5  from twisted.spread import pb 
  6   
  7  from twisted.spread.pb import PBClientFactory 
  8  from twisted.internet import protocol, reactor 
  9  from twisted.python import log 
 10   
11 -class ReconnectingPBClientFactory(PBClientFactory, 12 protocol.ReconnectingClientFactory):
13 """Reconnecting client factory for PB brokers. 14 15 Like PBClientFactory, but if the connection fails or is lost, the factory 16 will attempt to reconnect. 17 18 Instead of using f.getRootObject (which gives a Deferred that can only 19 be fired once), override the gotRootObject method. 20 21 Instead of using the newcred f.login (which is also one-shot), call 22 f.startLogin() with the credentials and client, and override the 23 gotPerspective method. 24 25 gotRootObject and gotPerspective will be called each time the object is 26 received (once per successful connection attempt). You will probably want 27 to use obj.notifyOnDisconnect to find out when the connection is lost. 28 29 If an authorization error occurs, failedToGetPerspective() will be 30 invoked. 31 32 To use me, subclass, then hand an instance to a connector (like 33 TCPClient). 34 """ 35 36 # hung connections wait for a relatively long time, since a busy master may 37 # take a while to get back to us. 38 hungConnectionTimer = None 39 HUNG_CONNECTION_TIMEOUT = 120 40
41 - def clientConnectionFailed(self, connector, reason):
42 PBClientFactory.clientConnectionFailed(self, connector, reason) 43 if self.continueTrying: 44 self.connector = connector 45 self.retry()
46
47 - def clientConnectionLost(self, connector, reason):
48 PBClientFactory.clientConnectionLost(self, connector, reason, 49 reconnecting=True) 50 RCF = protocol.ReconnectingClientFactory 51 RCF.clientConnectionLost(self, connector, reason)
52
53 - def startedConnecting(self, connector):
55
56 - def clientConnectionMade(self, broker):
57 self.resetDelay() 58 PBClientFactory.clientConnectionMade(self, broker) 59 self.doLogin(self._root) 60 self.gotRootObject(self._root)
61 62 # newcred methods 63
64 - def login(self, *args):
65 raise RuntimeError, "login is one-shot: use startLogin instead"
66
67 - def startLogin(self, credentials, client=None):
68 self._credentials = credentials 69 self._client = client
70
71 - def doLogin(self, root):
72 # newcred login() 73 d = self._cbSendUsername(root, self._credentials.username, 74 self._credentials.password, self._client) 75 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
76 77 # timer for hung connections 78
79 - def startHungConnectionTimer(self, connector):
80 self.stopHungConnectionTimer() 81 def hungConnection(): 82 log.msg("connection attempt timed out (is the port number correct?)") 83 self.hungConnectionTimer = None 84 connector.disconnect()
85 # (this will trigger the retry) 86 self.hungConnectionTimer = reactor.callLater(self.HUNG_CONNECTION_TIMEOUT, hungConnection)
87
88 - def stopHungConnectionTimer(self):
89 if self.hungConnectionTimer: 90 self.hungConnectionTimer.cancel() 91 self.hungConnectionTimer = None
92 93 # methods to override 94
95 - def gotPerspective(self, perspective):
96 """The remote avatar or perspective (obtained each time this factory 97 connects) is now available.""" 98 self.stopHungConnectionTimer()
99
100 - def gotRootObject(self, root):
101 """The remote root object (obtained each time this factory connects) 102 is now available. This method will be called each time the connection 103 is established and the object reference is retrieved.""" 104 self.stopHungConnectionTimer()
105
106 - def failedToGetPerspective(self, why):
107 """The login process failed, most likely because of an authorization 108 failure (bad password), but it is also possible that we lost the new 109 connection before we managed to send our credentials. 110 """ 111 log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 112 self.stopHungConnectionTimer() 113 if why.check(pb.PBConnectionLost): 114 log.msg("we lost the brand-new connection") 115 # retrying might help here, let clientConnectionLost decide 116 return 117 # probably authorization 118 self.stopTrying() # logging in harder won't help 119 log.err(why) 120 reactor.stop()
121