编写可维护的事件驱动代码

我最近刚刚开始使用事件驱动的体系结构,来自一个非常标准的面向对象的思维模式。

我注意到的第一件事是,通过程序理解和追踪的难度似乎随着程序的规模成倍地增加。 虽然小型宠物项目很容易遵循,但感觉就像代码将迅速转向意大利面。

我明白,我对这种发展思维是陌生的,并不是我所有的面向对象的担忧都会继续下去。 在编写可维护,可理解的事件驱动代码方面是否有任何资源? 使用node.js或Twisted或Event Machine的人对此做了什么?

我将使用Python作为示例,因为我正在使用它来构build庞大的分布式应用程序。

扭曲的python允许使用inlinecallbacks或(稍微丑陋的)deferredGenerator样式的非常必要的样式。 这些方法允许您编写使用事件驱动的callback代码的过程,这些代码更易于阅读和理解。 这个实现把你的函数变成一个延迟序列,产生一个延迟序列。

具体而言,您不必构build深度嵌套的callback函数/ lambdas / closures集合,而是可以在任意点处将function的控制权返回给事件循环。 如果你愿意的话,你可以在心理上重新标记为协程或合作多任务。 它完成了工作。 一个例子是(使用丑陋的deferredGenerator风格)像这样:

@defer.deferredGenerator def foo(arg): bar = nonBlockingFunction(foo) baz = waitForDeferred(aFunctionThatReturnsADeferredToo(bar)) yield baz #Returns control to the event loop output = baz.getResult() #This gets the output of aFunctionThat...Too above yield output #This is how we return a result instead of using return @defer.deferredGenerator def aFunctionThatReturnsADeferredToo(put_bar_here): """Stuff happens here....""" ...etc... 

这里有另一个post,显示inlineCallbacks方法,这是更清洁,但需要python 2.5或更新(意味着不在Centos / RHEL 5系列,我很遗憾地坚持我的应用程序下)。 如果你可以使用它做到这一点。

正如你所看到的,这看起来像老式的python命令性的东西,你知道和爱,但是没有大量的嵌套函数和lambdaexpression式,更容易维护。 我仍然希望Python有块。

至于debugging,可以使用初始化代码中的defer.setDebugging(True)调用打开debugging器的debugging。 这将附加在您的代码中引发exception的原始回溯,以便您可以细微地查看ACTUALLY发生的错误。 只要记住要在生产之前编辑setDebugging语句,因为它会导致大量额外的内省(如果你想完全惊骇地看着它)。

去年我在雅虎做过这个话题: http : //www.yuiblog.com/blog/2010/12/06/video-yuiconf2010-croucher/也许这很有用。

试着看看这些文章:

  • 了解node.js事件循环
  • 节点中的控制stream
  • 节点部分II中的控制stream程

Martyn Loughran写了一篇很好的短文,完全避免了回拨意大利面。

我对他的文章真正享受的是把意大利面条改进成漂亮干净的过程。 起初看起来可能有些forms化,但是当你看到最终的结果时,我认为你会同意他用干净,清晰的代码performance出真正的艺术性。

对于扭曲,而不是使用旧的deferredGenerator,我build议inlineCallbacks; 它使您可以完全编写阻塞式代码,并且仍然可以很好地与事件循环一起玩。

 @defer.inlineCallbacks def foo(arg): bar = nonBlockingFunction(foo) output = yield FunctionThatReturnsADeferredToo(bar) defer.returnValue(output) #This is how we return a result instead of using return 

显然已经有最佳实践和模式将会持续发展。

但是,也要考虑一下这样的可能性,即编程提供了“小宠物项目”互相交stream的机会。 想象一个世界,数以千计的分布式个人项目通过用户定义的callback实时交互。

用户和开发人员将能够从上到下重新连接现有协议的Web和应用程序,而不是依赖现有的应用程序devise。 然后,应用程序devise人员可以自由地关注个别用例,而不是提供一成不变的解决scheme,或担心每个可能的意外情况。

看看Web Hooks ,看看像Twilio这样的服务是如何运作的

我唯一的build议是认为function