Package buildbot :: Module pbutil
[hide private]
[frames] | no frames]

Source Code for Module buildbot.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 
  9  from twisted.python import log 
 10   
11 -class NewCredPerspective(pb.Avatar):
12 - def attached(self, mind):
13 return self
14 - def detached(self, mind):
15 pass
16
17 -class ReconnectingPBClientFactory(PBClientFactory, 18 protocol.ReconnectingClientFactory):
19 """Reconnecting client factory for PB brokers. 20 21 Like PBClientFactory, but if the connection fails or is lost, the factory 22 will attempt to reconnect. 23 24 Instead of using f.getRootObject (which gives a Deferred that can only 25 be fired once), override the gotRootObject method. 26 27 Instead of using the newcred f.login (which is also one-shot), call 28 f.startLogin() with the credentials and client, and override the 29 gotPerspective method. 30 31 Instead of using the oldcred f.getPerspective (also one-shot), call 32 f.startGettingPerspective() with the same arguments, and override 33 gotPerspective. 34 35 gotRootObject and gotPerspective will be called each time the object is 36 received (once per successful connection attempt). You will probably want 37 to use obj.notifyOnDisconnect to find out when the connection is lost. 38 39 If an authorization error occurs, failedToGetPerspective() will be 40 invoked. 41 42 To use me, subclass, then hand an instance to a connector (like 43 TCPClient). 44 """ 45
46 - def __init__(self):
47 PBClientFactory.__init__(self) 48 self._doingLogin = False 49 self._doingGetPerspective = False
50
51 - def clientConnectionFailed(self, connector, reason):
52 PBClientFactory.clientConnectionFailed(self, connector, reason) 53 # Twisted-1.3 erroneously abandons the connection on non-UserErrors. 54 # To avoid this bug, don't upcall, and implement the correct version 55 # of the method here. 56 if self.continueTrying: 57 self.connector = connector 58 self.retry()
59
60 - def clientConnectionLost(self, connector, reason):
61 PBClientFactory.clientConnectionLost(self, connector, reason, 62 reconnecting=True) 63 RCF = protocol.ReconnectingClientFactory 64 RCF.clientConnectionLost(self, connector, reason)
65
66 - def clientConnectionMade(self, broker):
67 self.resetDelay() 68 PBClientFactory.clientConnectionMade(self, broker) 69 if self._doingLogin: 70 self.doLogin(self._root) 71 if self._doingGetPerspective: 72 self.doGetPerspective(self._root) 73 self.gotRootObject(self._root)
74
75 - def __getstate__(self):
76 # this should get folded into ReconnectingClientFactory 77 d = self.__dict__.copy() 78 d['connector'] = None 79 d['_callID'] = None 80 return d
81 82 # oldcred methods 83
84 - def getPerspective(self, *args):
85 raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead"
86
87 - def startGettingPerspective(self, username, password, serviceName, 88 perspectiveName=None, client=None):
89 self._doingGetPerspective = True 90 if perspectiveName == None: 91 perspectiveName = username 92 self._oldcredArgs = (username, password, serviceName, 93 perspectiveName, client)
94
95 - def doGetPerspective(self, root):
96 # oldcred getPerspective() 97 (username, password, 98 serviceName, perspectiveName, client) = self._oldcredArgs 99 d = self._cbAuthIdentity(root, username, password) 100 d.addCallback(self._cbGetPerspective, 101 serviceName, perspectiveName, client) 102 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
103 104 105 # newcred methods 106
107 - def login(self, *args):
108 raise RuntimeError, "login is one-shot: use startLogin instead"
109
110 - def startLogin(self, credentials, client=None):
111 self._credentials = credentials 112 self._client = client 113 self._doingLogin = True
114
115 - def doLogin(self, root):
116 # newcred login() 117 d = self._cbSendUsername(root, self._credentials.username, 118 self._credentials.password, self._client) 119 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
120 121 122 # methods to override 123
124 - def gotPerspective(self, perspective):
125 """The remote avatar or perspective (obtained each time this factory 126 connects) is now available.""" 127 pass
128
129 - def gotRootObject(self, root):
130 """The remote root object (obtained each time this factory connects) 131 is now available. This method will be called each time the connection 132 is established and the object reference is retrieved.""" 133 pass
134
135 - def failedToGetPerspective(self, why):
136 """The login process failed, most likely because of an authorization 137 failure (bad password), but it is also possible that we lost the new 138 connection before we managed to send our credentials. 139 """ 140 log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 141 if why.check(pb.PBConnectionLost): 142 log.msg("we lost the brand-new connection") 143 # retrying might help here, let clientConnectionLost decide 144 return 145 # probably authorization 146 self.stopTrying() # logging in harder won't help 147 log.err(why)
148