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

Source Code for Module buildbot.pbutil

  1  # This file is part of Buildbot.  Buildbot is free software: you can 
  2  # redistribute it and/or modify it under the terms of the GNU General Public 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  5  # This program is distributed in the hope that it will be useful, but WITHOUT 
  6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 10  # You should have received a copy of the GNU General Public License along with 
 11  # this program; if not, write to the Free Software Foundation, Inc., 51 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 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 
 24  from twisted.python import log 
 25   
26 -class NewCredPerspective(pb.Avatar):
27 - def attached(self, mind):
28 return self
29 - def detached(self, mind):
30 pass
31
32 -class ReconnectingPBClientFactory(PBClientFactory, 33 protocol.ReconnectingClientFactory):
34 """Reconnecting client factory for PB brokers. 35 36 Like PBClientFactory, but if the connection fails or is lost, the factory 37 will attempt to reconnect. 38 39 Instead of using f.getRootObject (which gives a Deferred that can only 40 be fired once), override the gotRootObject method. 41 42 Instead of using the newcred f.login (which is also one-shot), call 43 f.startLogin() with the credentials and client, and override the 44 gotPerspective method. 45 46 Instead of using the oldcred f.getPerspective (also one-shot), call 47 f.startGettingPerspective() with the same arguments, and override 48 gotPerspective. 49 50 gotRootObject and gotPerspective will be called each time the object is 51 received (once per successful connection attempt). You will probably want 52 to use obj.notifyOnDisconnect to find out when the connection is lost. 53 54 If an authorization error occurs, failedToGetPerspective() will be 55 invoked. 56 57 To use me, subclass, then hand an instance to a connector (like 58 TCPClient). 59 """ 60
61 - def __init__(self):
62 PBClientFactory.__init__(self) 63 self._doingLogin = False 64 self._doingGetPerspective = False
65
66 - def clientConnectionFailed(self, connector, reason):
67 PBClientFactory.clientConnectionFailed(self, connector, reason) 68 # Twisted-1.3 erroneously abandons the connection on non-UserErrors. 69 # To avoid this bug, don't upcall, and implement the correct version 70 # of the method here. 71 if self.continueTrying: 72 self.connector = connector 73 self.retry()
74
75 - def clientConnectionLost(self, connector, reason):
76 PBClientFactory.clientConnectionLost(self, connector, reason, 77 reconnecting=True) 78 RCF = protocol.ReconnectingClientFactory 79 RCF.clientConnectionLost(self, connector, reason)
80
81 - def clientConnectionMade(self, broker):
82 self.resetDelay() 83 PBClientFactory.clientConnectionMade(self, broker) 84 if self._doingLogin: 85 self.doLogin(self._root) 86 if self._doingGetPerspective: 87 self.doGetPerspective(self._root) 88 self.gotRootObject(self._root)
89 90 # oldcred methods 91
92 - def getPerspective(self, *args):
93 raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead"
94
95 - def startGettingPerspective(self, username, password, serviceName, 96 perspectiveName=None, client=None):
97 self._doingGetPerspective = True 98 if perspectiveName == None: 99 perspectiveName = username 100 self._oldcredArgs = (username, password, serviceName, 101 perspectiveName, client)
102
103 - def doGetPerspective(self, root):
104 # oldcred getPerspective() 105 (username, password, 106 serviceName, perspectiveName, client) = self._oldcredArgs 107 d = self._cbAuthIdentity(root, username, password) 108 d.addCallback(self._cbGetPerspective, 109 serviceName, perspectiveName, client) 110 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
111 112 113 # newcred methods 114
115 - def login(self, *args):
116 raise RuntimeError, "login is one-shot: use startLogin instead"
117
118 - def startLogin(self, credentials, client=None):
119 self._credentials = credentials 120 self._client = client 121 self._doingLogin = True
122
123 - def doLogin(self, root):
124 # newcred login() 125 d = self._cbSendUsername(root, self._credentials.username, 126 self._credentials.password, self._client) 127 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
128 129 130 # methods to override 131
132 - def gotPerspective(self, perspective):
133 """The remote avatar or perspective (obtained each time this factory 134 connects) is now available.""" 135 pass
136
137 - def gotRootObject(self, root):
138 """The remote root object (obtained each time this factory connects) 139 is now available. This method will be called each time the connection 140 is established and the object reference is retrieved.""" 141 pass
142
143 - def failedToGetPerspective(self, why):
144 """The login process failed, most likely because of an authorization 145 failure (bad password), but it is also possible that we lost the new 146 connection before we managed to send our credentials. 147 """ 148 log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 149 if why.check(pb.PBConnectionLost): 150 log.msg("we lost the brand-new connection") 151 # retrying might help here, let clientConnectionLost decide 152 return 153 # probably authorization 154 self.stopTrying() # logging in harder won't help 155 log.err(why)
156