Package ZenUtils :: Module PBUtil
[hide private]
[frames] | no frames]

Source Code for Module ZenUtils.PBUtil

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  # taken from r1.10 of buildbot.sf.net/buildbot/pbutil.py 
 15   
 16  # flumotion has nearly the same code 
 17   
 18  """Base classes handy for use with PB clients. 
 19  """ 
 20   
 21  from twisted.spread import pb 
 22   
 23  from twisted.spread.pb import PBClientFactory 
 24  from twisted.internet import protocol 
 25  from twisted.python import log 
 26   
27 -class ReconnectingPBClientFactory(PBClientFactory, 28 protocol.ReconnectingClientFactory):
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 Instead of using the oldcred f.getPerspective (also one-shot), call 42 f.startGettingPerspective() with the same arguments, and override 43 gotPerspective. 44 45 gotRootObject and gotPerspective will be called each time the object is 46 received (once per successful connection attempt). You will probably want 47 to use obj.notifyOnDisconnect to find out when the connection is lost. 48 49 If an authorization error occurs, failedToGetPerspective() will be 50 invoked. 51 52 To use me, subclass, then hand an instance to a connector (like 53 TCPClient). 54 """ 55
56 - def __init__(self):
57 PBClientFactory.__init__(self) 58 self._doingLogin = False 59 self._doingGetPerspective = False
60
61 - def clientConnectionFailed(self, connector, reason):
62 PBClientFactory.clientConnectionFailed(self, connector, reason) 63 # Twisted-1.3 erroneously abandons the connection on non-UserErrors. 64 # To avoid this bug, don't upcall, and implement the correct version 65 # of the method here. 66 if self.continueTrying: 67 self.connector = connector 68 self.retry()
69
70 - def clientConnectionLost(self, connector, reason):
71 PBClientFactory.clientConnectionLost(self, connector, reason, 72 reconnecting=True) 73 RCF = protocol.ReconnectingClientFactory 74 RCF.clientConnectionLost(self, connector, reason)
75
76 - def clientConnectionMade(self, broker):
77 self.resetDelay() 78 PBClientFactory.clientConnectionMade(self, broker) 79 if self._doingLogin: 80 self.doLogin(self._root) 81 if self._doingGetPerspective: 82 self.doGetPerspective(self._root) 83 self.gotRootObject(self._root)
84
85 - def __getstate__(self):
86 # this should get folded into ReconnectingClientFactory 87 d = self.__dict__.copy() 88 d['connector'] = None 89 d['_callID'] = None 90 return d
91 92 # oldcred methods 93
94 - def getPerspective(self, *args):
95 raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead"
96
97 - def startGettingPerspective(self, username, password, serviceName, 98 perspectiveName=None, client=None):
99 self._doingGetPerspective = True 100 if perspectiveName == None: 101 perspectiveName = username 102 self._oldcredArgs = (username, password, serviceName, 103 perspectiveName, client)
104
105 - def doGetPerspective(self, root):
106 # oldcred getPerspective() 107 (username, password, 108 serviceName, perspectiveName, client) = self._oldcredArgs 109 d = self._cbAuthIdentity(root, username, password) 110 d.addCallback(self._cbGetPerspective, 111 serviceName, perspectiveName, client) 112 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
113 114 115 # newcred methods 116
117 - def login(self, *args):
118 raise RuntimeError, "login is one-shot: use startLogin instead"
119
120 - def startLogin(self, credentials, client=None):
121 self._credentials = credentials 122 self._client = client 123 self._doingLogin = True
124
125 - def doLogin(self, root):
126 # newcred login() 127 d = self._cbSendUsername(root, self._credentials.username, 128 self._credentials.password, self._client) 129 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective) 130 return d
131 132 133 # methods to override 134
135 - def gotPerspective(self, perspective):
136 """The remote avatar or perspective (obtained each time this factory 137 connects) is now available.""" 138 pass
139
140 - def gotRootObject(self, root):
141 """The remote root object (obtained each time this factory connects) 142 is now available. This method will be called each time the connection 143 is established and the object reference is retrieved.""" 144 pass
145
146 - def failedToGetPerspective(self, why):
147 """The login process failed, most likely because of an authorization 148 failure (bad password), but it is also possible that we lost the new 149 connection before we managed to send our credentials. 150 """ 151 log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 152 if why.check(pb.PBConnectionLost): 153 log.msg("we lost the brand-new connection") 154 # retrying might help here, let clientConnectionLost decide 155 return 156 # probably authorization 157 self.stopTrying() # logging in harder won't help 158 log.err(why)
159