Tornado 的 stack context

发布时间:2017-09-11 12:15:26
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

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:武汉SEO http://wuhan.raoyu.net