1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """
17 Contains stub classes.
18 Proxies (stubs) are the I{local} representation of I{remote}
19 classes on which we invoke methods.
20 """
21
22 from new import classobj
23 from threading import RLock
24 from gofer.messaging import *
25 from gofer.rmi.policy import *
26 from gofer.rmi.dispatcher import Request
27 from gofer.rmi.window import Window
31 """
32 A dynamic method object used to wrap the RMI call.
33 @ivar classname: The target class name.
34 @type classname: str
35 @ivar name: The target method name.
36 @type name: str
37 @ivar stub: The stub object used to send the AMQP message.
38 @type stub: L{Stub}
39 """
40
41 - def __init__(self, classname, name, stub):
42 """
43 @param classname: The target class name.
44 @type classname: str
45 @param name: The target method name.
46 @type name: str
47 @param stub: The stub object used to send the AMQP message.
48 @type stub: L{Stub}
49 """
50 self.classname = classname
51 self.name = name
52 self.stub = stub
53
55 """
56 Invoke the method .
57 @param args: The args.
58 @type args: list
59 @param kws: The I{keyword} arguments.
60 @type kws: dict
61 """
62 opts = Options()
63 for k,v in kws.items():
64 if k in ('window', 'any',):
65 opts[k] = v
66 del kws[k]
67 request = Request(
68 classname=self.classname,
69 method=self.name,
70 args=args,
71 kws=kws)
72 return self.stub._send(request, opts)
73
76 """
77 The stub class for remote objects.
78 @ivar __producer: An AMQP producer.
79 @type __producer: L{gofer.messaging.producer.Producer}
80 @ivar __destination: The AMQP destination
81 @type __destination: L{Destination}
82 @ivar __options: Stub options.
83 @type __options: L{Options}
84 @ivar __mutex: The object mutex.
85 @type __mutex: RLock
86 @ivar __policy: The invocation policy.
87 @type __policy: L{Policy}
88 """
89
90 @classmethod
91 - def stub(cls, name, producer, destination, options):
92 """
93 Factory method.
94 @param name: The stub class (or module) name.
95 @type name: str
96 @param destination: The AMQP destination
97 @type destination: L{Destination}
98 @param options: A dict of gofer options
99 @param options: L{Options}
100 @return: A stub instance.
101 @rtype: L{Stub}
102 """
103 subclass = classobj(name, (Stub,), {})
104 inst = subclass(producer, destination, options)
105 return inst
106
107 - def __init__(self, producer, destination, options):
108 """
109 @param producer: An AMQP producer.
110 @type producer: L{gofer.messaging.producer.Producer}
111 @param destination: The AMQP destination
112 @type destination: L{Destination}
113 @param options: Stub options.
114 @type options: L{Options}
115 """
116 self.__producer = producer
117 self.__destination = destination
118 self.__options = Options(options)
119 self.__called = (0, None)
120 self.__mutex = RLock()
121 self.__policy = None
122
123 - def _send(self, request, options):
124 """
125 Send the request using the configured request method.
126 @param request: An RMI request.
127 @type request: str
128 @param options: Invocation options.
129 @type options: L{Options}
130 """
131 self.__lock()
132 try:
133 return self.__send(request, options)
134 finally:
135 self.__unlock()
136
137 - def __send(self, request, options):
138 """
139 Send the request using the configured request method.
140 @param request: An RMI request.
141 @type request: str
142 @param options: Invocation options.
143 @type options: L{Options}
144 """
145 opts = Options(self.__options)
146 opts += options
147 request.cntr = self.__called[1]
148 policy = self.__getpolicy()
149 if isinstance(self.__destination, (list,tuple)):
150 return policy.broadcast(
151 self.__destination,
152 request,
153 window=opts.window,
154 secret=opts.secret,
155 pam=self.__getpam(opts),
156 any=opts.any)
157 else:
158 return policy.send(
159 self.__destination,
160 request,
161 window=opts.window,
162 secret=opts.secret,
163 pam=self.__getpam(opts),
164 any=opts.any)
165
167 """
168 Get PAM options.
169 @param opts: options dict.
170 @type opts: dict
171 @return: pam options
172 @rtype: L{Options}
173 """
174 user = opts.user
175 if opts.user:
176 return Options(
177 user=opts.user,
178 password=opts.password)
179 return None
180
182 """
183 Python vodo.
184 Get a I{Method} object for any requested attribte.
185 @param name: The attribute name.
186 @type name: str
187 @return: A method object.
188 @rtype: L{Method}
189 """
190 cn = self.__class__.__name__
191 return Method(cn, name, self)
192
194 """
195 Python vodo.
196 Get a I{Method} object for any requested attribte.
197 @param name: The attribute name.
198 @type name: str
199 @return: A method object.
200 @rtype: L{Method}
201 """
202 return getattr(self, name)
203
205 """
206 Simulated constructor.
207 The 1st call updates stub options.
208 The 2nd call updates remote object constructor
209 parameters which are passed on RMI calls.
210 @param options: keyword options.
211 @type options: dict
212 @return: self
213 @rtype: L{Stub}
214 """
215 if not self.__called[0]:
216 self.__called = (1, None)
217 self.__options += options
218 else:
219 n = self.__called[0]
220 self.__called = (n+1, (args, options))
221 return self
222
224 """
225 Get the request policy based on options.
226 The policy is cached for performance.
227 @return: The request policy.
228 @rtype: L{Policy}
229 """
230 if self.__policy is None:
231 self.__setpolicy()
232 return self.__policy
233
244
246 """
247 Get whether an I{asynchronous} request method
248 should be used based on selected options.
249 @return: True if async.
250 @rtype: bool
251 """
252 if ( self.__options.ctag or
253 self.__options.async or
254 self.__options.trigger):
255 return True
256 return isinstance(self.__destination, (list,tuple))
257
260
263