def __init__(self, io_loop, request, callback): self.start_time = time.time() self.io_loop = io_loop self.request = request self.callback = callback self.code = None self.headers = None self.chunks = None self._decompressor = None # Timeout handle returned by IOLoop.add_timeout self._timeout = None with stack_context.StackContext(self.cleanup): parsed = urlparse.urlsplit(self.request.url) if ":" in parsed.netloc: host, _, port = parsed.netloc.partition(":") port = int(port) else: host = parsed.netloc port = 443 if parsed.scheme == "https" else 80 if parsed.scheme == "https": # TODO: cert verification, etc self.stream = SSLIOStream(socket.socket(), io_loop=self.io_loop) else: self.stream = IOStream(socket.socket(), io_loop=self.io_loop) timeout = min(request.connect_timeout, request.request_timeout) if timeout: self._connect_timeout = self.io_loop.add_timeout( self.start_time + timeout, self._on_timeout) self.stream.connect((host, port), functools.partial(self._on_connect, parsed))
def send_message(self, message, with_last_error=False, callback=None): """Say something to Mongo. Raises ConnectionFailure if the message cannot be sent. Raises OperationFailure if `with_last_error` is ``True`` and the response to the getLastError call returns an error. Return the response from lastError, or ``None`` if `with_last_error` is ``False``. :Parameters: - `message`: message to send - `with_last_error`: check getLastError status after sending the message """ if self._callback is not None: raise ProgrammingError('connection already in use') if self.closed(): if self._autoreconnect: self._connect() else: raise InterfaceError( 'connection is closed and autoreconnect is false') self._callback = stack_context.wrap(callback) self._check_response = with_last_error with stack_context.StackContext(self.close_on_error): self.__send_message(message, with_last_error=with_last_error)
def _execute(self, transforms, *args, **kwargs): """If a user cookie is present, looks up the corresponding user object and stores it in the ViewfinderContext, along with the device_id and viewpoint_id fields of the cookie. The context is available for the execution of this request and can be retrieved by invoking the ViewfinderContext.current() method. """ @gen.engine def _ExecuteTarget(): """Invoked in the scope of a ViewfinderContext instance.""" try: ViewfinderContext.current( ).connection_close_event = self._connection_close_event self._current_user = None self._transforms = transforms client = DBClient.Instance() user_cookie_dict, user = yield self._ProcessCookie(client) if user is not None: self.LoginUser(user, user_cookie_dict) # Continue on with request processing. if not self._MaybeRedirect(): super(BaseHandler, self)._execute(transforms, *args, **kwargs) except Exception as e: self._handle_request_exception(e) # Establish Viewfinder context, and then call another func, since it is not safe to use a # yield in the static scope of the "with stack_context" statement. with stack_context.StackContext(ViewfinderContext(self.request)): _ExecuteTarget()
def _execute(self, transforms, *args, **kwargs): #该函数是继承自web.py中 current_context = {'request': self.request} with stack_context.StackContext( functools.partial(ThreadlocalLikeRequestContext, **current_context)): return super(_HandlerPatch, self)._execute(transforms, *args, **kwargs)
def _execute(self, transforms, *args, **kwargs): @engine def _execute_impl(): user_cookie_dict, user = yield self.get_user_from_cookie() if user is not None: self.login_user(user, user_cookie_dict) super(BaseHandler, self)._execute(transforms, *args, **kwargs) with stack_context.StackContext(BaseContext(self.request)): _execute_impl()
def function_with_stack_context(self, callback): # Technically this function should stack_context.wrap its callback # upon entry. However, it is very common for this step to be # omitted. def step2(): self.assertEqual(self.named_contexts, ['a']) self.io_loop.add_callback(callback) with stack_context.StackContext(self.named_context('a')): self.io_loop.add_callback(step2)
def EnterOpContext(op): """Returns a StackContext that when entered, puts the given operation into scope in a new OpContext. """ @contextmanager def _ContextManager(op): with OpContext(): with OpContext.current().Enter(op): yield return stack_context.StackContext(partial(_ContextManager, op))
def _gthing(fwait): assert _current_stackcontext() is None sc = stack_context.StackContext(_mgr) with sc: assert _current_stackcontext() is sc greenado.gyield(fwait) assert _current_stackcontext() is sc return True
def _main(): f = gen.Future() def _doit(): f.set_result(True) with stack_context.NullContext(): IOLoop.current().add_callback(_doit) with stack_context.StackContext(_mgr): return greenado.gyield(f)
def send_command(self, fullcmd, expect_str, callback): self._final_callback = callback if self._stream.closed(): self.connect() with stack_context.StackContext(self.cleanup): if fullcmd[0:3] == 'get' or \ fullcmd[0:4] == 'incr' or \ fullcmd[0:4] == 'decr': self._stream.write(fullcmd, self.read_value) else: self._stream.write( fullcmd, functools.partial(self.read_response, expect_str))
def Execute(self, operation_id=None, wait_callback=None): """Starts execution of all operations for the managed user. Once all operations have been completed, or if another server is already executing the operations, then the callback passed to __init__ is invoked. If the "operation_id" argument is provided, it is used as a hint as to where to start execution. However, if an operation with a lower id is found in the database, that is executed first, in order to ensure that the server executes operations in the same order that a device submitted them. If "wait_callback" is specified, then it is invoked when the "operation_id" operation is complete (but other operations for the user may still be running). If "operation_id" is None in this case, then "wait_callback" will only be invoked once all operations for this user are complete. """ def _OnCompletedOp(type=None, value=None, tb=None): """Wraps the caller's callback so that it is called in the original context, and any exception is raised in the original context. """ if (type, value, tb) != (None, None, None): raise type, value, tb wait_callback() @gen.engine def _ExecuteAll(): """Executes all ops within the scope of an OpContext. "yield" is not supported in the static scope of OpContext, which is why this is a separate function. """ try: self._is_executing = True self._requery = True while self._requery: yield self._ExecuteAll(operation_id=operation_id) finally: # Notify any remaining listeners that their operations are complete (since all operations are now complete). for cb_op_id in self._sync_cb_map.keys(): self._InvokeSyncCallbacks(cb_op_id) # Complete execution. self._is_executing = False self._callback() # Add callbacks for synchronous case. if wait_callback is not None: self._sync_cb_map[operation_id].append(stack_context.wrap(_OnCompletedOp)) if not self._is_executing: # Establish op context, and then call another func, since it is not safe to use a yield in the static scope # of the "with stack_context" statement. with stack_context.StackContext(OpContext()): _ExecuteAll() else: # Sets flag so that once all operations are executed, the list of operations is re-queried # in order to find any newly added operations. self._requery = True
def _main(): fwait = gen.Future() sc = stack_context.StackContext(_mgr) assert _current_stackcontext() is None with sc: assert _current_stackcontext() is sc f = greenado.gcall(_gthing, sc, fwait) assert _current_stackcontext() is sc fwait.set_result(True) assert _current_stackcontext() is sc assert _current_stackcontext() is None return f
def __init__(self, io_loop, client, request, callback): self.start_time = time.time() self.io_loop = io_loop self.client = client self.request = request self.callback = callback self.code = None self.headers = None self.chunks = None self._decompressor = None # Timeout handle returned by IOLoop.add_timeout self._timeout = None with stack_context.StackContext(self.cleanup): parsed = urlparse.urlsplit(self.request.url) if ":" in parsed.netloc: host, _, port = parsed.netloc.partition(":") port = int(port) else: host = parsed.netloc port = 443 if parsed.scheme == "https" else 80 if self.client.hostname_mapping is not None: host = self.client.hostname_mapping.get(host, host) if parsed.scheme == "https": ssl_options = {} if request.validate_cert: ssl_options["cert_reqs"] = ssl.CERT_REQUIRED if request.ca_certs is not None: ssl_options["ca_certs"] = request.ca_certs else: ssl_options["ca_certs"] = _DEFAULT_CA_CERTS self.stream = SSLIOStream(socket.socket(), io_loop=self.io_loop, ssl_options=ssl_options) else: self.stream = IOStream(socket.socket(), io_loop=self.io_loop) timeout = min(request.connect_timeout, request.request_timeout) if timeout: self._connect_timeout = self.io_loop.add_timeout( self.start_time + timeout, self._on_timeout) self.stream.set_close_callback(self._on_close) self.stream.connect((host, port), functools.partial(self._on_connect, parsed))
def testWithStackContext1(self): """Ensure Retry preserves StackContext.""" self.__in_context = False @contextlib.contextmanager def _MyContext(): try: self.__in_context = True yield finally: self.__in_context = False def _OnCompletedCheckContext(result, error): self.assertTrue(self.__in_context) self.stop() with stack_context.StackContext(_MyContext): retry_policy = retry.RetryPolicy(max_tries=2, check_result=lambda res, err: err) retry.CallWithRetryAsync(retry_policy, self._AsyncFuncFailOnce, callback=_OnCompletedCheckContext) self.wait()
def send_message_with_response(self, message, callback): """Send a message to Mongo and return the response. Sends the given message and returns the response. :Parameters: - `message`: (request_id, data) pair making up the message to send """ if self._callback is not None: raise ProgrammingError('connection already in use') if self.closed(): if self._autoreconnect: self._connect() else: raise InterfaceError( 'connection is closed and autoreconnect is false') self._callback = stack_context.wrap(callback) self._check_response = False with stack_context.StackContext(self.close_on_error): self.__send_message_and_receive(message)
def __init__(self, io_loop, client, request, release_callback, final_callback, max_buffer_size): self.start_time = time.time() self.io_loop = io_loop self.client = client self.request = request self.release_callback = release_callback self.final_callback = final_callback self.code = None self.headers = None self.chunks = None self._decompressor = None # Timeout handle returned by IOLoop.add_timeout self._timeout = None with stack_context.StackContext(self.cleanup): parsed = urlparse.urlsplit(_unicode(self.request.url)) if ssl is None and parsed.scheme == "https": raise ValueError("HTTPS requires either python2.6+ or " "curl_httpclient") if parsed.scheme not in ("http", "https"): raise ValueError("Unsupported url scheme: %s" % self.request.url) # urlsplit results have hostname and port results, but they # didn't support ipv6 literals until python 2.7. netloc = parsed.netloc if "@" in netloc: userpass, _, netloc = netloc.rpartition("@") match = re.match(r'^(.+):(\d+)$', netloc) if match: host = match.group(1) port = int(match.group(2)) else: host = netloc port = 443 if parsed.scheme == "https" else 80 if re.match(r'^\[.*\]$', host): # raw ipv6 addresses in urls are enclosed in brackets host = host[1:-1] if self.client.hostname_mapping is not None: host = self.client.hostname_mapping.get(host, host) if request.allow_ipv6: af = socket.AF_UNSPEC else: # We only try the first IP we get from getaddrinfo, # so restrict to ipv4 by default. af = socket.AF_INET addrinfo = socket.getaddrinfo(host, port, af, socket.SOCK_STREAM, 0, 0) af, socktype, proto, canonname, sockaddr = addrinfo[0] if parsed.scheme == "https": ssl_options = {} if request.validate_cert: ssl_options["cert_reqs"] = ssl.CERT_REQUIRED if request.ca_certs is not None: ssl_options["ca_certs"] = request.ca_certs else: ssl_options["ca_certs"] = _DEFAULT_CA_CERTS if request.client_key is not None: ssl_options["keyfile"] = request.client_key if request.client_cert is not None: ssl_options["certfile"] = request.client_cert self.stream = SSLIOStream(socket.socket(af, socktype, proto), io_loop=self.io_loop, ssl_options=ssl_options, max_buffer_size=max_buffer_size) else: self.stream = IOStream(socket.socket(af, socktype, proto), io_loop=self.io_loop, max_buffer_size=max_buffer_size) timeout = min(request.connect_timeout, request.request_timeout) if timeout: self._timeout = self.io_loop.add_timeout( self.start_time + timeout, self._on_timeout) self.stream.set_close_callback(self._on_close) self.stream.connect(sockaddr, functools.partial(self._on_connect, parsed))
def __init__(self, io_loop, client, request, release_callback, final_callback, max_buffer_size): self.start_time = time.time() self.io_loop = io_loop self.client = client self.request = request self.release_callback = release_callback self.final_callback = final_callback self.code = None self.headers = None self.chunks = None self._decompressor = None # Timeout handle returned by IOLoop.add_timeout self._timeout = None with stack_context.StackContext(self.cleanup): parsed = urlparse.urlsplit(_unicode(self.request.url)) if ssl is None and parsed.scheme == "https": raise ValueError("HTTPS requires either python2.6+ or " "curl_httpclient") if parsed.scheme not in ("http", "https"): raise ValueError("Unsupported url scheme: %s" % self.request.url) # urlsplit results have hostname and port results, but they # didn't support ipv6 literals until python 2.7. netloc = parsed.netloc if "@" in netloc: userpass, _, netloc = netloc.rpartition("@") match = re.match(r'^(.+):(\d+)$', netloc) if match: host = match.group(1) port = int(match.group(2)) else: host = netloc port = 443 if parsed.scheme == "https" else 80 if re.match(r'^\[.*\]$', host): # raw ipv6 addresses in urls are enclosed in brackets host = host[1:-1] if self.client.hostname_mapping is not None: host = self.client.hostname_mapping.get(host, host) if request.allow_ipv6: af = socket.AF_UNSPEC else: # We only try the first IP we get from getaddrinfo, # so restrict to ipv4 by default. af = socket.AF_INET addrinfo = socket.getaddrinfo(host, port, af, socket.SOCK_STREAM, 0, 0) af, socktype, proto, canonname, sockaddr = addrinfo[0] if parsed.scheme == "https": ssl_options = {} if request.validate_cert: ssl_options["cert_reqs"] = ssl.CERT_REQUIRED if request.ca_certs is not None: ssl_options["ca_certs"] = request.ca_certs else: ssl_options["ca_certs"] = _DEFAULT_CA_CERTS if request.client_key is not None: ssl_options["keyfile"] = request.client_key if request.client_cert is not None: ssl_options["certfile"] = request.client_cert # SSL interoperability is tricky. We want to disable # SSLv2 for security reasons; it wasn't disabled by default # until openssl 1.0. The best way to do this is to use # the SSL_OP_NO_SSLv2, but that wasn't exposed to python # until 3.2. Python 2.7 adds the ciphers argument, which # can also be used to disable SSLv2. As a last resort # on python 2.6, we set ssl_version to SSLv3. This is # more narrow than we'd like since it also breaks # compatibility with servers configured for TLSv1 only, # but nearly all servers support SSLv3: # http://blog.ivanristic.com/2011/09/ssl-survey-protocol-support.html if sys.version_info >= (2, 7): ssl_options["ciphers"] = "DEFAULT:!SSLv2" else: # This is really only necessary for pre-1.0 versions # of openssl, but python 2.6 doesn't expose version # information. ssl_options["ssl_version"] = ssl.PROTOCOL_SSLv3 self.stream = SSLIOStream(socket.socket(af, socktype, proto), io_loop=self.io_loop, ssl_options=ssl_options, max_buffer_size=max_buffer_size) else: self.stream = IOStream(socket.socket(af, socktype, proto), io_loop=self.io_loop, max_buffer_size=max_buffer_size) timeout = min(request.connect_timeout, request.request_timeout) if timeout: self._timeout = self.io_loop.add_timeout( self.start_time + timeout, self._on_timeout) self.stream.set_close_callback(self._on_close) self.stream.connect(sockaddr, functools.partial(self._on_connect, parsed))
def _main(): with stack_context.StackContext(_mgr): greenado.gsleep(0.1) return True
def run_coroutine(span, coro): def mgr(): return RequestContextManager(span) with stack_context.StackContext(mgr): return coro()
def LoggingStackContext(self, logger=None): """Returns a tornado StackContext which adds this handler to the given logger when entered, removing it upon exit. If no logger is given, the default logger from logging.getLogger will be used. """ return stack_context.StackContext(partial(self.LoggingContext, logger))
def make_context(self): return stack_context.StackContext(self.__context)
def __call__(self): return stack_context.StackContext(functools.partial(set_context, self))
def _main(): with stack_context.StackContext(_mgr): greenado.gyield(_fn()) return True
@contextlib.contextmanager def die_on_error(): try: yield except Exception: logging.error("exception in asynchronous operation", exc_info=True) sys.exit(1) def foo(data): print('aa') # for i in xrange(10): # print ('begin %d' % i) # Any exception thrown here *or in callback and its descendants* # http_client = httpclient.AsyncHTTPClient() # http_client.fetch("http://www.baidu.com", foo) # print('end %d' % i) for i in xrange(1): with stack_context.StackContext(die_on_error): print('begin %d' % i) # Any exception thrown here *or in callback and its descendants* # will cause the process to exit instead of spinning endlessly # in the ioloop. # http_client = httpclient.AsyncHTTPClient() # http_client.fetch("http://www1.baidu.com", foo) 1 / 0 print('end %d' % i) IOLoop.current().start()