1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
57 PBClientFactory.__init__(self)
58 self._doingLogin = False
59 self._doingGetPerspective = False
60
62 PBClientFactory.clientConnectionFailed(self, connector, reason)
63
64
65
66 if self.continueTrying:
67 self.connector = connector
68 self.retry()
69
75
84
86
87 d = self.__dict__.copy()
88 d['connector'] = None
89 d['_callID'] = None
90 return d
91
92
93
95 raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead"
96
99 self._doingGetPerspective = True
100 if perspectiveName == None:
101 perspectiveName = username
102 self._oldcredArgs = (username, password, serviceName,
103 perspectiveName, client)
104
106
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
116
118 raise RuntimeError, "login is one-shot: use startLogin instead"
119
121 self._credentials = credentials
122 self._client = client
123 self._doingLogin = True
124
131
132
133
134
136 """The remote avatar or perspective (obtained each time this factory
137 connects) is now available."""
138 pass
139
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
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
155 return
156
157 self.stopTrying()
158 log.err(why)
159