def synchronized_method(*args, **kwargs): assert "callback" not in kwargs, "Cannot pass callback to synchronized method" # In Motor, passing a callback is like passing w=1 unless # overridden explicitly with a w=0 kwarg. To emulate PyMongo, pass # w=0 if necessary. safe, opts = False, {} try: gle_opts = dict([(k, v) for k, v in kwargs.items() if k in SAFE_OPTIONS.union(set(["safe"]))]) safe, opts = self.delegate.delegate._get_write_mode(**gle_opts) except (AttributeError, InvalidOperation): # Delegate not set yet, or no _get_write_mode method. # Since, as of Tornado 2.3, IOStream tries to divine the error # that closed it using sys.exc_info(), it's important here to # clear spurious errors sys.exc_clear() if has_write_concern: kwargs["w"] = opts.get("w", 1) if safe else 0 kwargs.pop("safe", None) loop = IOLoop.instance() assert not loop.running(), "Loop already running in method %s" % async_method.func_name loop._callbacks[:] = [] loop._timeouts[:] = [] outcome = {} def raise_timeout_err(): loop.stop() outcome["error"] = TimeoutError("timeout") timeout = loop.add_timeout(time.time() + timeout_sec, raise_timeout_err) def callback(result, error): try: loop.stop() loop.remove_timeout(timeout) outcome["result"] = result outcome["error"] = error except Exception: traceback.print_exc(sys.stderr) raise kwargs["callback"] = callback if getattr(async_method, "has_write_concern", False): kwargs.setdefault("w", self.write_concern.get("w", 1)) async_method(*args, **kwargs) try: loop.start() if outcome.get("error"): raise outcome["error"] return outcome["result"] finally: if loop.running(): loop.stop()
def synchronized_method(*args, **kwargs): assert 'callback' not in kwargs, ( "Cannot pass callback to synchronized method") # TODO: remove after PYTHON-452 is done safe, opts = False, {} try: gle_opts = dict([(k, v) for k, v in kwargs.items() if k in SAFE_OPTIONS.union(set(['safe']))]) safe, opts = self.delegate.delegate._get_write_mode(**gle_opts) except (AttributeError, InvalidOperation): # Delegate not set yet, or no _get_write_mode method. # Since, as of Tornado 2.3, IOStream tries to divine the error # that closed it using sys.exc_info(), it's important here to # clear spurious errors sys.exc_clear() if not safe and has_write_concern: # By default, Motor passes safe=True if there's a callback, but # we're emulating PyMongo's Connection, which defaults safe to # False, so we explicitly override. kwargs['w'] = 0 kwargs.pop('safe', None) loop = IOLoop.instance() assert not loop.running(), \ "Loop already running in method %s" % async_method.func_name loop._callbacks[:] = [] loop._timeouts[:] = [] outcome = {} def raise_timeout_err(): loop.stop() outcome['error'] = TimeoutError("timeout") timeout = loop.add_timeout( time.time() + timeout_sec, raise_timeout_err) def callback(result, error): try: loop.stop() loop.remove_timeout(timeout) outcome['result'] = result outcome['error'] = error except Exception: traceback.print_exc(sys.stderr) raise kwargs['callback'] = callback async_method(*args, **kwargs) try: loop.start() if outcome.get('error'): raise outcome['error'] return outcome['result'] finally: if loop.running(): loop.stop()