Handle requests from the proxies in a particular process/thread
(self, conn)
| 240 | conn.close() |
| 241 | |
| 242 | def serve_client(self, conn): |
| 243 | ''' |
| 244 | Handle requests from the proxies in a particular process/thread |
| 245 | ''' |
| 246 | util.debug('starting server thread to service %r', |
| 247 | threading.current_thread().name) |
| 248 | |
| 249 | recv = conn.recv |
| 250 | send = conn.send |
| 251 | id_to_obj = self.id_to_obj |
| 252 | |
| 253 | while not self.stop_event.is_set(): |
| 254 | |
| 255 | try: |
| 256 | methodname = obj = None |
| 257 | request = recv() |
| 258 | ident, methodname, args, kwds = request |
| 259 | try: |
| 260 | obj, exposed, gettypeid = id_to_obj[ident] |
| 261 | except KeyError as ke: |
| 262 | try: |
| 263 | obj, exposed, gettypeid = \ |
| 264 | self.id_to_local_proxy_obj[ident] |
| 265 | except KeyError: |
| 266 | raise ke |
| 267 | |
| 268 | if methodname not in exposed: |
| 269 | raise AttributeError( |
| 270 | 'method %r of %r object is not in exposed=%r' % |
| 271 | (methodname, type(obj), exposed) |
| 272 | ) |
| 273 | |
| 274 | function = getattr(obj, methodname) |
| 275 | |
| 276 | try: |
| 277 | res = function(*args, **kwds) |
| 278 | except Exception as e: |
| 279 | msg = ('#ERROR', e) |
| 280 | else: |
| 281 | typeid = gettypeid and gettypeid.get(methodname, None) |
| 282 | if typeid: |
| 283 | rident, rexposed = self.create(conn, typeid, res) |
| 284 | token = Token(typeid, self.address, rident) |
| 285 | msg = ('#PROXY', (rexposed, token)) |
| 286 | else: |
| 287 | msg = ('#RETURN', res) |
| 288 | |
| 289 | except AttributeError: |
| 290 | if methodname is None: |
| 291 | msg = ('#TRACEBACK', format_exc()) |
| 292 | else: |
| 293 | try: |
| 294 | fallback_func = self.fallback_mapping[methodname] |
| 295 | result = fallback_func( |
| 296 | self, conn, ident, obj, *args, **kwds |
| 297 | ) |
| 298 | msg = ('#RETURN', result) |
| 299 | except Exception: |