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

Source Code for Module Products.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(secs) set to 5 minute maximum delay before attempting to 59 # reconnect 60 maxDelay = 300 61
62 - def __init__(self):
63 PBClientFactory.__init__(self) 64 self._doingLogin = False 65 self._doingGetPerspective = False
66
67 - def clientConnectionFailed(self, connector, reason):
68 PBClientFactory.clientConnectionFailed(self, connector, reason) 69 # Twisted-1.3 erroneously abandons the connection on non-UserErrors. 70 # To avoid this bug, don't upcall, and implement the correct version 71 # of the method here. 72 if self.continueTrying: 73 self.connector = connector 74 self.retry()
75
76 - def clientConnectionLost(self, connector, reason, reconnecting=1):
77 PBClientFactory.clientConnectionLost(self, connector, reason, 78 reconnecting=reconnecting) 79 RCF = protocol.ReconnectingClientFactory 80 RCF.clientConnectionLost(self, connector, reason)
81
82 - def clientConnectionMade(self, broker):
83 self.resetDelay() 84 PBClientFactory.clientConnectionMade(self, broker) 85 if self._doingLogin: 86 self.doLogin(self._root) 87 if self._doingGetPerspective: 88 self.doGetPerspective(self._root) 89 self.gotRootObject(self._root)
90
91 - def __getstate__(self):
92 # this should get folded into ReconnectingClientFactory 93 d = self.__dict__.copy() 94 d['connector'] = None 95 d['_callID'] = None 96 return d
97 98 # oldcred methods 99
100 - def getPerspective(self, *args):
101 raise RuntimeError( "getPerspective is one-shot: use startGettingPerspective instead" )
102
103 - def startGettingPerspective(self, username, password, serviceName, 104 perspectiveName=None, client=None):
105 self._doingGetPerspective = True 106 if perspectiveName == None: 107 perspectiveName = username 108 self._oldcredArgs = (username, password, serviceName, 109 perspectiveName, client)
110
111 - def doGetPerspective(self, root):
112 # oldcred getPerspective() 113 (username, password, 114 serviceName, perspectiveName, client) = self._oldcredArgs 115 d = self._cbAuthIdentity(root, username, password) 116 d.addCallback(self._cbGetPerspective, 117 serviceName, perspectiveName, client) 118 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
119 120 121 # newcred methods 122
123 - def login(self, credentials, client=None):
124 from Products.ZenUtils.Utils import unused 125 unused(credentials, client) 126 raise RuntimeError( "Login is one-shot: use startLogin instead" )
127
128 - def startLogin(self, credentials, client=None):
129 self._credentials = credentials 130 self._client = client 131 self._doingLogin = True
132
133 - def doLogin(self, root):
134 # newcred login() 135 d = self._cbSendUsername(root, self._credentials.username, 136 self._credentials.password, self._client) 137 d.addCallbacks(self.gotPerspective, self.failedToGetPerspective) 138 return d
139 140 141 # methods to override 142
143 - def gotPerspective(self, perspective):
144 """The remote avatar or perspective (obtained each time this factory 145 connects) is now available.""" 146 pass
147
148 - def gotRootObject(self, root):
149 """The remote root object (obtained each time this factory connects) 150 is now available. This method will be called each time the connection 151 is established and the object reference is retrieved.""" 152 pass
153
154 - def failedToGetPerspective(self, why):
155 """The login process failed, most likely because of an authorization 156 failure (bad password), but it is also possible that we lost the new 157 connection before we managed to send our credentials. 158 """ 159 log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 160 if why.check(pb.PBConnectionLost): 161 log.msg("we lost the brand-new connection") 162 # retrying might help here, let clientConnectionLost decide 163 return 164 # probably authorization 165 self.stopTrying() # logging in harder won't help 166 log.err(why)
167