本文整理汇总了Python中tornado.concurrent.TracebackFuture.set_exception方法的典型用法代码示例。如果您正苦于以下问题:Python TracebackFuture.set_exception方法的具体用法?Python TracebackFuture.set_exception怎么用?Python TracebackFuture.set_exception使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类tornado.concurrent.TracebackFuture
的用法示例。
在下文中一共展示了TracebackFuture.set_exception方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: wrapper
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def wrapper(*args, **kwargs):
future = TracebackFuture()
try:
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
result = getattr(e, 'value', None)
except Exception:
future.set_exc_info(sys.exc_info())
return future
else:
if isinstance(result, types.GeneratorType):
# Inline the first iteration of Runner.run. This lets us
# avoid the cost of creating a Runner when the coroutine
# never actually yields, which in turn allows us to
# use "optional" coroutines in critical path code without
# performance penalty for the synchronous case.
try:
orig_stack_contexts = stack_context._state.contexts
yielded = next(result)
if stack_context._state.contexts is not orig_stack_contexts:
yielded = TracebackFuture()
yielded.set_exception(
stack_context.StackContextInconsistentError(
'stack_context inconsistency (probably caused '
'by yield within a "with StackContext" block)'))
except (StopIteration, Return) as e:
future.set_result(getattr(e, 'value', None))
except Exception:
future.set_exc_info(sys.exc_info())
else:
# post runner into Cocaine ioloop
CocaineIO.instance().post(Runner, result, future, yielded)
return future
future.set_result(result)
return future
示例2: wrapper
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def wrapper(*args, **kwargs):
future = TracebackFuture()
if replace_callback and "callback" in kwargs:
callback = kwargs.pop("callback")
IOLoop.current().add_future(future, lambda future: callback(future.result()))
try:
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
result = _value_from_stopiteration(e)
except Exception:
future.set_exc_info(sys.exc_info())
return future
else:
if isinstance(result, GeneratorType):
# Inline the first iteration of Runner.run. This lets us
# avoid the cost of creating a Runner when the coroutine
# never actually yields, which in turn allows us to
# use "optional" coroutines in critical path code without
# performance penalty for the synchronous case.
try:
orig_stack_contexts = stack_context._state.contexts
yielded = next(result)
if stack_context._state.contexts is not orig_stack_contexts:
yielded = TracebackFuture()
yielded.set_exception(
stack_context.StackContextInconsistentError(
"stack_context inconsistency (probably caused "
'by yield within a "with StackContext" block)'
)
)
except (StopIteration, Return) as e:
future.set_result(_value_from_stopiteration(e))
except Exception:
future.set_exc_info(sys.exc_info())
else:
_futures_to_runners[future] = Runner(result, future, yielded)
try:
return future
finally:
# Subtle memory optimization: if next() raised an exception,
# the future's exc_info contains a traceback which
# includes this stack frame. This creates a cycle,
# which will be collected at the next full GC but has
# been shown to greatly increase memory usage of
# benchmarks (relative to the refcount-based scheme
# used in the absence of cycles). We can avoid the
# cycle by clearing the local variable after we return it.
future = None
future.set_result(result)
return future
示例3: wrapper
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def wrapper(*args, **kwargs):
ipdb.set_trace()
future = TracebackFuture()
if replace_callback and 'callback' in kwargs:
callback = kwargs.pop('callback')
IOLoop.current().add_future(future, lambda future: callback(future.result()))
try:
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
# ipdb.set_trace()
result = gen._value_from_stopiteration(e)
except Exception:
# ipdb.set_trace()
future.set_exc_info(sys.exc_info())
return future
else:
# ipdb.set_trace()
if isinstance(result, GeneratorType):
try:
orig_stack_contexts = stack_context._state.contexts
yielded = next(result)
if stack_context._state.contexts is not orig_stack_contexts:
yielded = TracebackFuture()
yielded.set_exception(stack_context.StackContextInconsistentError('stack_context inconsistency (probably caused'))
except (StopIteration, Return) as e:
future.set_result(gen._value_from_stopiteration(e))
except Exception:
future.set_exc_info(sys.exc_info())
else:
try:
result.send(yielded.result())
except (StopIteration, Return) as e:
ipdb.set_trace()
future.set_result(gen._value_from_stopiteration(e))
# gen.Runner(result, future, yielded)
try:
return future
finally:
future = None
future.set_result(result)
return future
示例4: wrapper
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def wrapper(*args, **kwargs):
future = TracebackFuture()
if replace_callback and 'callback' in kwargs:
callback = kwargs.pop('callback')
IOLoop.current().add_future(
future, lambda future: callback(future.result()))
try:
with Measure(func):
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
result = getattr(e, 'value', None)
except Exception:
future.set_exc_info(sys.exc_info())
return future
else:
if isinstance(result, types.GeneratorType):
try:
orig_stack_contexts = stack_context._state.contexts
with Measure(result, first=True):
yielded = next(result)
if stack_context._state.contexts is not orig_stack_contexts:
yielded = TracebackFuture()
yielded.set_exception(
stack_context.StackContextInconsistentError(
'stack_context inconsistency (probably caused '
'by yield within a "with StackContext" block)'))
except (StopIteration, Return) as e:
future.set_result(getattr(e, 'value', None))
except Exception:
future.set_exc_info(sys.exc_info())
else:
Runner(result, future, yielded)
try:
return future
finally:
future = None
future.set_result(result)
return future
示例5: wrapper
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def wrapper(*args, **kwargs):
future = TracebackFuture()
if replace_callback and "callback" in kwargs:
callback = kwargs.pop("callback")
IOLoop.current().add_future(future, lambda future: callback(future.result()))
try:
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
result = getattr(e, "value", None)
except Exception:
future.set_exc_info(sys.exc_info())
return future
else:
if isinstance(result, types.GeneratorType):
# Inline the first iteration of Runner.run. This lets us
# avoid the cost of creating a Runner when the coroutine
# never actually yields, which in turn allows us to
# use "optional" coroutines in critical path code without
# performance penalty for the synchronous case.
try:
orig_stack_contexts = stack_context._state.contexts
yielded = next(result)
if stack_context._state.contexts is not orig_stack_contexts:
yielded = TracebackFuture()
yielded.set_exception(
stack_context.StackContextInconsistentError(
"stack_context inconsistency (probably caused "
'by yield within a "with StackContext" block)'
)
)
except (StopIteration, Return) as e:
future.set_result(getattr(e, "value", None))
except Exception:
future.set_exc_info(sys.exc_info())
else:
Runner(result, future, yielded)
return future
future.set_result(result)
return future
示例6: get_connection
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def get_connection(self):
future = TracebackFuture()
if self._closed:
future.set_exception(ConnectionPoolClosedError())
return future
if not self._connections:
if self._connections_count < self._max_connections:
def _(succed, result):
if succed:
self._used_connections.append(result)
future.set_result(result)
else:
future.set_exc_info(result)
self.init_connection(_)
else:
self._wait_connections.append(future)
else:
connection = self._connections.popleft()
self._used_connections.append(connection)
future.set_result(connection)
return future
示例7: WebSocketClientConnection
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class WebSocketClientConnection(simple_httpclient._HTTPConnection):
"""WebSocket client connection.
This class should not be instantiated directly; use the
`websocket_connect` function instead.
"""
def __init__(self, io_loop, request):
self.connect_future = TracebackFuture()
self.read_future = None
self.read_queue = collections.deque()
self.key = base64.b64encode(os.urandom(16))
scheme, sep, rest = request.url.partition(':')
scheme = {'ws': 'http', 'wss': 'https'}[scheme]
request.url = scheme + sep + rest
request.headers.update({
'Upgrade': 'websocket',
'Connection': 'Upgrade',
'Sec-WebSocket-Key': self.key,
'Sec-WebSocket-Version': '13',
})
self.resolver = Resolver(io_loop=io_loop)
super(WebSocketClientConnection, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response,
104857600, self.resolver)
def close(self):
"""Closes the websocket connection.
.. versionadded:: 3.2
"""
if self.protocol is not None:
self.protocol.close()
self.protocol = None
def _on_close(self):
self.on_message(None)
self.resolver.close()
super(WebSocketClientConnection, self)._on_close()
def _on_http_response(self, response):
if not self.connect_future.done():
if response.error:
self.connect_future.set_exception(response.error)
else:
self.connect_future.set_exception(WebSocketError(
"Non-websocket response"))
def _handle_1xx(self, code):
assert code == 101
assert self.headers['Upgrade'].lower() == 'websocket'
assert self.headers['Connection'].lower() == 'upgrade'
accept = WebSocketProtocol13.compute_accept_value(self.key)
assert self.headers['Sec-Websocket-Accept'] == accept
self.protocol = WebSocketProtocol13(self, mask_outgoing=True)
self.protocol._receive_frame()
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
self.connect_future.set_result(self)
def write_message(self, message, binary=False):
"""Sends a message to the WebSocket server."""
self.protocol.write_message(message, binary)
def read_message(self, callback=None):
"""Reads a message from the WebSocket server.
Returns a future whose result is the message, or None
if the connection is closed. If a callback argument
is given it will be called with the future when it is
ready.
"""
assert self.read_future is None
future = TracebackFuture()
if self.read_queue:
future.set_result(self.read_queue.popleft())
else:
self.read_future = future
if callback is not None:
self.io_loop.add_future(future, callback)
return future
def on_message(self, message):
if self.read_future is not None:
self.read_future.set_result(message)
self.read_future = None
else:
self.read_queue.append(message)
def on_pong(self, data):
pass
示例8: WebSocketClientConnection
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class WebSocketClientConnection(simple_httpclient._HTTPConnection):
"""WebSocket client connection.
This class should not be instantiated directly; use the
`websocket_connect` function instead.
"""
def __init__(self, io_loop, request, on_message_callback=None,
compression_options=None):
self.compression_options = compression_options
self.connect_future = TracebackFuture()
self.protocol = None
self.read_future = None
self.read_queue = collections.deque()
self.key = base64.b64encode(os.urandom(16))
self._on_message_callback = on_message_callback
self.close_code = self.close_reason = None
scheme, sep, rest = request.url.partition(':')
scheme = {'ws': 'http', 'wss': 'https'}[scheme]
request.url = scheme + sep + rest
request.headers.update({
'Upgrade': 'websocket',
'Connection': 'Upgrade',
'Sec-WebSocket-Key': self.key,
'Sec-WebSocket-Version': '13',
})
if self.compression_options is not None:
# Always offer to let the server set our max_wbits (and even though
# we don't offer it, we will accept a client_no_context_takeover
# from the server).
# TODO: set server parameters for deflate extension
# if requested in self.compression_options.
request.headers['Sec-WebSocket-Extensions'] = (
'permessage-deflate; client_max_window_bits')
self.tcp_client = TCPClient(io_loop=io_loop)
super(WebSocketClientConnection, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response,
104857600, self.tcp_client, 65536, 104857600)
def close(self, code=None, reason=None):
"""Closes the websocket connection.
``code`` and ``reason`` are documented under
`WebSocketHandler.close`.
.. versionadded:: 3.2
.. versionchanged:: 4.0
Added the ``code`` and ``reason`` arguments.
"""
if self.protocol is not None:
self.protocol.close(code, reason)
self.protocol = None
def on_connection_close(self):
if not self.connect_future.done():
self.connect_future.set_exception(StreamClosedError())
self.on_message(None)
self.tcp_client.close()
super(WebSocketClientConnection, self).on_connection_close()
def _on_http_response(self, response):
if not self.connect_future.done():
if response.error:
self.connect_future.set_exception(response.error)
else:
self.connect_future.set_exception(WebSocketError(
"Non-websocket response"))
def headers_received(self, start_line, headers):
if start_line.code != 101:
return super(WebSocketClientConnection, self).headers_received(
start_line, headers)
self.headers = headers
self.protocol = self.get_websocket_protocol()
self.protocol._process_server_headers(self.key, self.headers)
self.protocol._receive_frame()
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
self.stream = self.connection.detach()
self.stream.set_close_callback(self.on_connection_close)
# Once we've taken over the connection, clear the final callback
# we set on the http request. This deactivates the error handling
# in simple_httpclient that would otherwise interfere with our
# ability to see exceptions.
self.final_callback = None
self.connect_future.set_result(self)
def write_message(self, message, binary=False):
"""Sends a message to the WebSocket server."""
return self.protocol.write_message(message, binary)
def read_message(self, callback=None):
#.........这里部分代码省略.........
示例9: Runner
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
#.........这里部分代码省略.........
yielded = self.gen.send(value)
if stack_context._state.contexts is not orig_stack_contexts:
self.gen.throw(
stack_context.StackContextInconsistentError(
'stack_context inconsistency (probably caused '
'by yield within a "with StackContext" block)'))
except (StopIteration, Return) as e:
self.finished = True
self.future = _null_future
if self.pending_callbacks and not self.had_exception:
# If we ran cleanly without waiting on all callbacks
# raise an error (really more of a warning). If we
# had an exception then some callbacks may have been
# orphaned, so skip the check in that case.
raise LeakedCallbackError(
"finished without waiting for callbacks %r" %
self.pending_callbacks)
self.result_future.set_result(getattr(e, 'value', None))
self.result_future = None
self._deactivate_stack_context()
return
except Exception:
self.finished = True
self.future = _null_future
self.result_future.set_exc_info(sys.exc_info())
self.result_future = None
self._deactivate_stack_context()
return
if not self.handle_yield(yielded):
return
finally:
self.running = False
def handle_yield(self, yielded):
if isinstance(yielded, list):
if all(is_future(f) for f in yielded):
yielded = multi_future(yielded)
else:
yielded = Multi(yielded)
elif isinstance(yielded, dict):
if all(is_future(f) for f in yielded.values()):
yielded = multi_future(yielded)
else:
yielded = Multi(yielded)
if isinstance(yielded, YieldPoint):
self.future = TracebackFuture()
def start_yield_point():
try:
yielded.start(self)
if yielded.is_ready():
self.future.set_result(
yielded.get_result())
else:
self.yield_point = yielded
except Exception:
self.future = TracebackFuture()
self.future.set_exc_info(sys.exc_info())
if self.stack_context_deactivate is None:
# Start a stack context if this is the first
# YieldPoint we've seen.
with stack_context.ExceptionStackContext(
self.handle_exception) as deactivate:
self.stack_context_deactivate = deactivate
def cb():
start_yield_point()
self.run()
self.io_loop.add_callback(cb)
return False
else:
start_yield_point()
elif is_future(yielded):
self.future = yielded
if not self.future.done() or self.future is moment:
self.io_loop.add_future(
self.future, lambda f: self.run())
return False
else:
self.future = TracebackFuture()
self.future.set_exception(BadYieldError(
"yielded unknown object %r" % (yielded,)))
return True
def result_callback(self, key):
return stack_context.wrap(_argument_adapter(
functools.partial(self.set_result, key)))
def handle_exception(self, typ, value, tb):
if not self.running and not self.finished:
self.future = TracebackFuture()
self.future.set_exc_info((typ, value, tb))
self.run()
return True
else:
return False
def _deactivate_stack_context(self):
if self.stack_context_deactivate is not None:
self.stack_context_deactivate()
self.stack_context_deactivate = None
示例10: EventSourceClient
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class EventSourceClient(simple_httpclient._HTTPConnection):
"""
This module opens a new connection to an eventsource server, and wait for events.
"""
def __init__(self, io_loop, request):
self.connect_future = TracebackFuture()
self.read_future = None
self.read_queue = collections.deque()
self.events = []
if old_tornado:
self.resolver = Resolver(io_loop=io_loop)
super(EventSourceClient, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response,
104857600, self.resolver)
else:
self.tcp_client = TCPClient(io_loop=io_loop)
super(EventSourceClient, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response,
104857600, self.tcp_client, 65536)
def _handle_event_stream(self):
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
self.stream.read_until_regex(b"\n\n", self.handle_stream)
self.connect_future.set_result(self)
def _on_http_response(self, response):
if not self.connect_future.done():
if response.error:
self.connect_future.set_exception(response.error)
else:
self.connect_future.set_exception(EventSourceError(
"Non-websocket response"))
def _on_headers(self, data):
data = native_str(data.decode("latin1"))
first_line, _, header_data = data.partition("\n")
match = re.match("HTTP/1.[01] ([0-9]+) ([^\r]*)", first_line)
assert match
code = int(match.group(1))
headers = httputil.HTTPHeaders.parse(header_data)
reason = match.group(2)
self.headers_received(HeadersData(code=code, reason=reason), headers)
def headers_received(self, data, headers):
self.headers = headers
self.code = data.code
self.reason = data.reason
if self.headers['Content-Type'] != 'text/event-stream':
raise ValueError("Invalid headers: %s" % self.headers)
if "Content-Length" in self.headers:
if "," in self.headers["Content-Length"]:
pieces = re.split(r',\s*', self.headers["Content-Length"])
if any(i != pieces[0] for i in pieces):
raise ValueError("Multiple unequal Content-Lengths: %r" %
self.headers["Content-Length"])
self.headers["Content-Length"] = pieces[0]
self._handle_event_stream()
def handle_stream(self, message):
"""
Acts on message reception
:param message: string of an incoming message
parse all the fields and builds an Event object that is passed to the callback function
"""
logging.debug("handle_stream(...)")
event = Event()
for line in message.strip().splitlines():
(field, value) = line.split(":", 1)
field = field.strip()
if field == "event":
event.name = value.lstrip()
elif field == "data":
value = value.lstrip()
if event.data is None:
event.data = value
else:
event.data = "%s\n%s" % (event.data, value)
elif field == "id":
event.id = value.lstrip()
self.last_event_id = event.id
elif field == "retry":
try:
self.retry_timeout = int(value)
event.retry = self.retry_timeout
logging.info("timeout reset: %s" % (value,))
except ValueError:
pass
elif field == "":
logging.debug("received comment: %s" % (value,))
else:
raise Exception("Unknown field !")
#.........这里部分代码省略.........
示例11: WebSocketClientConnection
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class WebSocketClientConnection(simple_httpclient._HTTPConnection):
"""WebSocket 客户端连接
这个类不应当直接被实例化, 请使用 `websocket_connect`
"""
def __init__(self, io_loop, request, on_message_callback=None,
compression_options=None):
self.compression_options = compression_options
self.connect_future = TracebackFuture()
self.protocol = None
self.read_future = None
self.read_queue = collections.deque()
self.key = base64.b64encode(os.urandom(16))
self._on_message_callback = on_message_callback
self.close_code = self.close_reason = None
scheme, sep, rest = request.url.partition(':')
scheme = {'ws': 'http', 'wss': 'https'}[scheme]
request.url = scheme + sep + rest
request.headers.update({
'Upgrade': 'websocket',
'Connection': 'Upgrade',
'Sec-WebSocket-Key': self.key,
'Sec-WebSocket-Version': '13',
})
if self.compression_options is not None:
# Always offer to let the server set our max_wbits (and even though
# we don't offer it, we will accept a client_no_context_takeover
# from the server).
# TODO: set server parameters for deflate extension
# if requested in self.compression_options.
request.headers['Sec-WebSocket-Extensions'] = (
'permessage-deflate; client_max_window_bits')
self.tcp_client = TCPClient(io_loop=io_loop)
super(WebSocketClientConnection, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response,
104857600, self.tcp_client, 65536, 104857600)
def close(self, code=None, reason=None):
"""关闭 websocket 连接
``code`` 和 ``reason`` 的文档在 `WebSocketHandler.close` 下已给出.
.. versionadded:: 3.2
.. versionchanged:: 4.0
添加 ``code`` 和 ``reason`` 这两个参数
"""
if self.protocol is not None:
self.protocol.close(code, reason)
self.protocol = None
def on_connection_close(self):
if not self.connect_future.done():
self.connect_future.set_exception(StreamClosedError())
self.on_message(None)
self.tcp_client.close()
super(WebSocketClientConnection, self).on_connection_close()
def _on_http_response(self, response):
if not self.connect_future.done():
if response.error:
self.connect_future.set_exception(response.error)
else:
self.connect_future.set_exception(WebSocketError(
"Non-websocket response"))
def headers_received(self, start_line, headers):
if start_line.code != 101:
return super(WebSocketClientConnection, self).headers_received(
start_line, headers)
self.headers = headers
self.protocol = self.get_websocket_protocol()
self.protocol._process_server_headers(self.key, self.headers)
self.protocol._receive_frame()
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
self.stream = self.connection.detach()
self.stream.set_close_callback(self.on_connection_close)
# Once we've taken over the connection, clear the final callback
# we set on the http request. This deactivates the error handling
# in simple_httpclient that would otherwise interfere with our
# ability to see exceptions.
self.final_callback = None
self.connect_future.set_result(self)
def write_message(self, message, binary=False):
"""发送消息到 websocket 服务器."""
return self.protocol.write_message(message, binary)
def read_message(self, callback=None):
"""读取来自 WebSocket 服务器的消息.
#.........这里部分代码省略.........
示例12: WebSocketClientConnection
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class WebSocketClientConnection(simple_httpclient._HTTPConnection):
"""WebSocket client connection.
This class should not be instantiated directly; use the
`websocket_connect` function instead.
"""
def __init__(self, io_loop, request):
self.connect_future = TracebackFuture()
self.read_future = None
self.read_queue = collections.deque()
self.key = base64.b64encode(os.urandom(16))
scheme, sep, rest = request.url.partition(":")
scheme = {"ws": "http", "wss": "https"}[scheme]
request.url = scheme + sep + rest
request.headers.update(
{
"Upgrade": "websocket",
"Connection": "Upgrade",
"Sec-WebSocket-Key": self.key,
"Sec-WebSocket-Version": "13",
}
)
self.tcp_client = TCPClient(io_loop=io_loop)
super(WebSocketClientConnection, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response, 104857600, self.tcp_client, 65536
)
def close(self, code=None, reason=None):
"""Closes the websocket connection.
``code`` and ``reason`` are documented under
`WebSocketHandler.close`.
.. versionadded:: 3.2
.. versionchanged:: 4.0
Added the ``code`` and ``reason`` arguments.
"""
if self.protocol is not None:
self.protocol.close(code, reason)
self.protocol = None
def _on_close(self):
self.on_message(None)
self.resolver.close()
super(WebSocketClientConnection, self)._on_close()
def _on_http_response(self, response):
if not self.connect_future.done():
if response.error:
self.connect_future.set_exception(response.error)
else:
self.connect_future.set_exception(WebSocketError("Non-websocket response"))
def headers_received(self, start_line, headers):
if start_line.code != 101:
return super(WebSocketClientConnection, self).headers_received(start_line, headers)
self.headers = headers
assert self.headers["Upgrade"].lower() == "websocket"
assert self.headers["Connection"].lower() == "upgrade"
accept = WebSocketProtocol13.compute_accept_value(self.key)
assert self.headers["Sec-Websocket-Accept"] == accept
self.protocol = WebSocketProtocol13(self, mask_outgoing=True)
self.protocol._receive_frame()
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
self.stream = self.connection.detach()
self.stream.set_close_callback(self._on_close)
self.connect_future.set_result(self)
def write_message(self, message, binary=False):
"""Sends a message to the WebSocket server."""
self.protocol.write_message(message, binary)
def read_message(self, callback=None):
"""Reads a message from the WebSocket server.
Returns a future whose result is the message, or None
if the connection is closed. If a callback argument
is given it will be called with the future when it is
ready.
"""
assert self.read_future is None
future = TracebackFuture()
if self.read_queue:
future.set_result(self.read_queue.popleft())
else:
self.read_future = future
if callback is not None:
self.io_loop.add_future(future, callback)
#.........这里部分代码省略.........
示例13: wrapper
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
def wrapper(*args, **kwargs):
future = TracebackFuture() # 一个future的跟踪对象,这个是关键
# 原来的func不支持callback的参数,修饰之后是可以使用的
# 下面的这个future好好读懂,然后好好理解传说中的future功能
if replace_callback and 'callback' in kwargs:
callback = kwargs.pop('callback')
# 就是future成功了,执行lambda future: callback(future.result())函数,参数就是这个future
# 也就是把这个可能执行的语句放到IOLoop里面去,这个就是这个add_future的功能
IOLoop.current().add_future(
future, lambda future: callback(future.result()))
# 异步的HTTP和异步的IOStream也许返回的类型不一样,
# 感觉两个异步的东西才是tornado的关键
try:
# 尝试运行函数,这里会yield出来,所以不会被阻塞的
# 1. 返回一个Return 2. 返回一个StopIteration(这个不是很清楚??)
# 3. 返回一个Exception?就是运行错误了
result = func(*args, **kwargs)
except (Return, StopIteration) as e:
# 到这里说明结果已经出来了,future的任务结束了
# ?StopIteration无法理解
result = getattr(e, 'value', None)
except Exception: # 如果出错的话
# 运行出错了,这个时候依旧会添加到IOLoop._callbacks
# 下面这句话执行这个future全部的回调
future.set_exc_info(sys.exc_info())
return future # 一但结果确定,直接返回一个future
else:
# 如果内部有yield,直接返回一个types.GeneratorType
if isinstance(result, types.GeneratorType):
# Inline the first iteration of Runner.run. This lets us
# avoid the cost of creating a Runner when the coroutine
# never actually yields, which in turn allows us to
# use "optional" coroutines in critical path code without
# performance penalty for the synchronous case.
try:
orig_stack_contexts = stack_context._state.contexts
# 这里是获取yield的结果的地方,一般还是一个future的东西
yielded = next(result) # 获取yield的结果,这里一般是一个future类型yield出来的东西
# 先忽略下面的出错处理
if stack_context._state.contexts is not orig_stack_contexts:
yielded = TracebackFuture()
yielded.set_exception(
stack_context.StackContextInconsistentError(
'stack_context inconsistency (probably caused '
'by yield within a "with StackContext" block)'))
except (StopIteration, Return) as e: # 直接出结果
future.set_result(getattr(e, 'value', None))
except Exception: # bug了
future.set_exc_info(sys.exc_info())
else: # 返回一个future
Runner(result, future, yielded)
# 如果是一个Exception,这里记录到future,然后返回了
return future
future.set_result(result) # 这个时候添加回调到了IOLoop
return future
示例14: AsyncResult
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class AsyncResult(object):
"""
Essentially a wrapper for a Tornado TracebackFuture
"""
def __init__(self, future=None):
if future is not None:
self._future = future
else:
self._future = TracebackFuture()
self._future.add_done_callback(functools.partial(async_result_complete, self))
self._condition = threading.Condition()
def ready(self):
"""Return `True` if and only if it holds a value or an
exception"""
return self._future.done()
def successful(self):
"""Return `True` if and only if it is ready and holds a
value"""
return self._future.exception() is None
@property
def exception(self):
return self._future.exception()
def set(self, value=None):
"""Store the value. Wake up the waiters.
:param value: Value to store as the result.
Any waiters blocking on :meth:`get` or :meth:`wait` are woken
up. Sequential calls to :meth:`wait` and :meth:`get` will not
block at all."""
with self._condition:
self._future.set_result(value)
def set_exception(self, exception):
"""Store the exception. Wake up the waiters.
:param exception: Exception to raise when fetching the value.
Any waiters blocking on :meth:`get` or :meth:`wait` are woken
up. Sequential calls to :meth:`wait` and :meth:`get` will not
block at all."""
with self._condition:
self._future.set_exception(exception)
def get(self, block=True, timeout=None):
"""Return the stored value or raise the exception
:param block: Whether this method should block or return
immediately.
:type block: bool
:param timeout: How long to wait for a value when `block` is
`True`.
:type timeout: float
If this instance already holds a value / an exception, return /
raise it immediately. Otherwise, block until :meth:`set` or
:meth:`set_exception` has been called or until the optional
timeout occurs."""
with self._condition:
if self.ready():
return self._future.result()
elif block:
self._condition.wait(timeout)
return self._future.result()
# if we get to this point we timeout
raise KazooTimeoutError()
def get_nowait(self):
"""Return the value or raise the exception without blocking.
If nothing is available, raise the Timeout exception class on
the associated :class:`IHandler` interface."""
return self._future.result()
def wait(self, timeout=None):
"""Block until the instance is ready.
:param timeout: How long to wait for a value
:type timeout: float
If this instance already holds a value / an exception, return /
raise it immediately. Otherwise, block until :meth:`set` or
:meth:`set_exception` has been called or until the optional
timeout occurs."""
with self._condition:
self._condition.wait(timeout)
return self.ready()
def rawlink(self, callback):
"""Register a callback to call when a value or an exception is
set
:param callback:
A callback function to call after :meth:`set` or
:meth:`set_exception` has been called. This function will
#.........这里部分代码省略.........
示例15: WebSocketClientConnection
# 需要导入模块: from tornado.concurrent import TracebackFuture [as 别名]
# 或者: from tornado.concurrent.TracebackFuture import set_exception [as 别名]
class WebSocketClientConnection(simple_httpclient._HTTPConnection):
"""WebSocket client connection."""
def __init__(self, io_loop, request):
self.connect_future = TracebackFuture()
self.read_future = None
self.read_queue = collections.deque()
self.key = base64.b64encode(os.urandom(16))
scheme, sep, rest = request.url.partition(":")
scheme = {"ws": "http", "wss": "https"}[scheme]
request.url = scheme + sep + rest
request.headers.update(
{
"Upgrade": "websocket",
"Connection": "Upgrade",
"Sec-WebSocket-Key": self.key,
"Sec-WebSocket-Version": "13",
}
)
self.resolver = Resolver(io_loop=io_loop)
super(WebSocketClientConnection, self).__init__(
io_loop, None, request, lambda: None, self._on_http_response, 104857600, self.resolver
)
def _on_close(self):
self.on_message(None)
self.resolver.close()
def _on_http_response(self, response):
if not self.connect_future.done():
if response.error:
self.connect_future.set_exception(response.error)
else:
self.connect_future.set_exception(WebSocketError("Non-websocket response"))
def _handle_1xx(self, code):
assert code == 101
assert self.headers["Upgrade"].lower() == "websocket"
assert self.headers["Connection"].lower() == "upgrade"
accept = WebSocketProtocol13.compute_accept_value(self.key)
assert self.headers["Sec-Websocket-Accept"] == accept
self.protocol = WebSocketProtocol13(self, mask_outgoing=True)
self.protocol._receive_frame()
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
self.connect_future.set_result(self)
def write_message(self, message, binary=False):
"""Sends a message to the WebSocket server."""
self.protocol.write_message(message, binary)
def read_message(self, callback=None):
"""Reads a message from the WebSocket server.
Returns a future whose result is the message, or None
if the connection is closed. If a callback argument
is given it will be called with the future when it is
ready.
"""
assert self.read_future is None
future = TracebackFuture()
if self.read_queue:
future.set_result(self.read_queue.popleft())
else:
self.read_future = future
if callback is not None:
self.io_loop.add_future(future, callback)
return future
def on_message(self, message):
if self.read_future is not None:
self.read_future.set_result(message)
self.read_future = None
else:
self.read_queue.append(message)
def on_pong(self, data):
pass