1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 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   
 31   
 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   
 62          PBClientFactory.__init__(self) 
 63          self._doingLogin = False 
 64          self._doingGetPerspective = False 
  65   
 74   
 80   
 89   
 90       
 91   
 93          raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead" 
  94   
 97          self._doingGetPerspective = True 
 98          if perspectiveName == None: 
 99              perspectiveName = username 
100          self._oldcredArgs = (username, password, serviceName, 
101                               perspectiveName, client) 
 102   
104           
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       
114   
116          raise RuntimeError, "login is one-shot: use startLogin instead" 
 117   
119          self._credentials = credentials 
120          self._client = client 
121          self._doingLogin = True 
 122   
128   
129   
130       
131   
133          """The remote avatar or perspective (obtained each time this factory 
134          connects) is now available.""" 
135          pass 
 136   
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   
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               
152              return 
153           
154          self.stopTrying()  
155          log.err(why) 
  156