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