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   
 16   
 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   
 47          PBClientFactory.__init__(self) 
 48          self._doingLogin = False 
 49          self._doingGetPerspective = False 
  50   
 59   
 65   
 74   
 75       
 76   
 78          raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead" 
  79   
 82          self._doingGetPerspective = True 
 83          if perspectiveName == None: 
 84              perspectiveName = username 
 85          self._oldcredArgs = (username, password, serviceName, 
 86                               perspectiveName, client) 
  87   
 89           
 90          (username, password, 
 91           serviceName, perspectiveName, client) = self._oldcredArgs 
 92          d = self._cbAuthIdentity(root, username, password) 
 93          d.addCallback(self._cbGetPerspective, 
 94                        serviceName, perspectiveName, client) 
 95          d.addCallbacks(self.gotPerspective, self.failedToGetPerspective) 
  96   
 97   
 98       
 99   
101          raise RuntimeError, "login is one-shot: use startLogin instead" 
 102   
104          self._credentials = credentials 
105          self._client = client 
106          self._doingLogin = True 
 107   
113   
114   
115       
116   
118          """The remote avatar or perspective (obtained each time this factory 
119          connects) is now available.""" 
120          pass 
 121   
123          """The remote root object (obtained each time this factory connects) 
124          is now available. This method will be called each time the connection 
125          is established and the object reference is retrieved.""" 
126          pass 
 127   
129          """The login process failed, most likely because of an authorization 
130          failure (bad password), but it is also possible that we lost the new 
131          connection before we managed to send our credentials. 
132          """ 
133          log.msg("ReconnectingPBClientFactory.failedToGetPerspective") 
134          if why.check(pb.PBConnectionLost): 
135              log.msg("we lost the brand-new connection") 
136               
137              return 
138           
139          self.stopTrying()  
140          log.err(why) 
  141