Package gofer :: Package rmi :: Module stub
[hide private]
[frames] | no frames]

Source Code for Module gofer.rmi.stub

  1  # 
  2  # Copyright (c) 2011 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU Lesser General Public 
  5  # License as published by the Free Software Foundation; either version 
  6  # 2 of the License (LGPLv2) or (at your option) any later version. 
  7  # There is NO WARRANTY for this software, express or implied, 
  8  # including the implied warranties of MERCHANTABILITY, 
  9  # NON-INFRINGEMENT, or FITNESS FOR A PARTICULAR PURPOSE. You should 
 10  # have received a copy of LGPLv2 along with this software; if not, see 
 11  # http://www.gnu.org/licenses/old-licenses/lgpl-2.0.txt. 
 12  # 
 13  # Jeff Ortel <jortel@redhat.com> 
 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 
28 29 30 -class Method:
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
54 - def __call__(self, *args, **kws):
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
74 75 -class Stub:
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
166 - def __getpam(self, opts):
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
181 - def __getattr__(self, name):
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
193 - def __getitem__(self, name):
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
204 - def __call__(self, *args, **options):
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
223 - def __getpolicy(self):
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
234 - def __setpolicy(self):
235 """ 236 Set the request policy based on options. 237 """ 238 if self.__async(): 239 self.__policy = \ 240 Asynchronous(self.__producer, self.__options) 241 else: 242 self.__policy = \ 243 Synchronous(self.__producer, self.__options)
244
245 - def __async(self):
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
258 - def __lock(self):
259 self.__mutex.acquire()
260
261 - def __unlock(self):
262 self.__mutex.release()
263