Tornado 的 stack context
Stack context 的意图就是为执行程序保存一个上下文,在需要的时候,可以回到这个上下文执行,包括异常,都可以更好地、统一地处理。这个功能的代码不是很多,也比较清晰,但是文档……嗯,至少我是没看明白,结合 httpclient 的源码作为例子,加上看 stack_context 的代码,大概明白了是怎么用了。
首先,在希望抓住问题的入口的地方要留住上下文:
#......
context = partial(self._cleanup, fail_callback = fail_callback)
with stack_context.StackContext(context):
getattr(c, cmd)(*args, **kwargs)
这里,后面的执行内容,包括回调、触发事件,都可以通过抛出异常退到这里,而管理异常的就是 context,这里,用 functools.partial 包装了一下 _cleanup,_cleanup 的写法大致是这样的:
@contextlib.contextmanager
def _cleanup(self, fail_callback = None):
try:
yield
except _Error as e:
print "gotcha", e
if fail_callback:
fail_callback(e.args)
这里,异常会被捕获,并调用用户指定的出错回调函数进行处理。后面的代码里,遇到故障,抛出异常就可以了,比如,可以用这个异常来返回超时:
def _on_timeout(self, server):
self._timeout = None
server.mark_dead('Time out')
raise _Error('memcache call timeout')
这个异常是通过 io_loop 的 timeout 方法来触发的:
self._timeout = self.io_loop.add_timeout(
time.time() + self.request_timeout,
stack_context.wrap(partial(self._on_timeout, server)))
这样,就可以在异步程序里比较干净地处理掉超时问题了。
这个代码对我这个水平的初学者还是比较晦涩的,大家可以参考下 HTTPClient 的源码,等我把这个 memcached client 的代码改完之后,也会放出来供参考指正的。
—-
update2: 放这里了 https://github.com/gnawux/tornado-memcache , get 测试过,其他还没有,另外,我不是多个 server sharding 的应用场景,相关的还没测试。
update :对于 timeout,设上了表忘了清除,如果是其他方式抛异常退出的话,也在抛异常的地方或者是最后处理异常的时候,把超时去掉
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
补充:Web开发 , Python ,