Nebula
Nebula
使用说明

Nebula是一个事件驱动型框架,事件分为“请求”和“响应”两种。请求事件都由不同功能模块处理,响应事件由指定的Step回调类对象处理。 Cmd类和Module类同为请求事件对应模块的处理入口,其中Cmd类用于事件中带有Cmd功能码的请求,Module用于带有url_path的http请求。Cmd和Module可以理解为某些框架的EventHandler。许多网络框架的EventHandler通过pipeline.add_last()方式添加到事件处理队列,一个事件到来从pipeline头部到尾部流过一个一个Handler,Handler根据eventType判断是否处理,不处理的就直接调用next Handler的处理方法,需要处理的就在处理完后调用next Handler处理方法。Nebula中不是通过pipeline来处理的,我们认为每个event都只会有一个处理者(Cmd或Module),事件的处理过程可能在单个Cmd或Module内就处理完毕,也可能需要经过几个步骤(Step)才处理完。因此,Nebula的Cmd和Module都是用hash表存储,event到来时直接定位到对应的Cmd或Module处理。 我们来看看Cmd类的声明: C++ Module类的声明: C++

Step类是异步IO处理的关键。在分布式系统中编程,任何一个任务,都可能被分解到不同节点,通过多次网络通信组合来完成。为了让每个服务进程达到足够高的并发,异步非阻塞编程模型是最好的选择,没有之一。而采用异步非阻塞编程模型意味着属于一个任务的代码被分割成很多个回调函数,在代码的各处被串接起来,非常不利于代码阅读,也不符合大部分人的思维习惯。到处都是回调函数,更甚者,使用“观察者模式”在一个地方注册大量的“事件-响应函数”,然后在所有需要回调的地方,都发出一个事件。使用“观察者模式”的代码,比单纯的注册回调函数更难理解,因为事件对应的响应函数,通常在发出事件处是无法找到的,往往都放在另外的一些文件里,而且有时候这些函数还会在运行时改变。而事件名本身往往也不是一个名符其实的名字。协程、Future/Promise模型、lamda模型等是为了解决回调函数对于代码可读性的破坏作用而设计和引入的。在Nebula,有另一种解决方案,就是Step类。

在Nebula,有另一种解决方案,就是Step类。通过Step类将回调的上下文关联起来,Step::Emit()是发出IO请求,Step::Callback()是IO请求所对应的响应回调,回调的上下文信息保存在Step类的成员变量里。这样一种设计让IO请求和响应看起来从未离开过同一个类对象,也无须传递上下文信息,与同步IO相比差异在于:同步的IO请求和响应在同一个函数的前后两行代码,而Step异步IO是在同一个类的两个不同成员函数。Step类实现异步IO比直接写回调函数、观察者模式、Future/Promise模型、lamda模型都更为直观,更容易编写和理解,又比协程实现更为节省空间,并发能力更强。实质上,Step类底层还是通过回调函数实现的,只是回调实现的复杂性由Nebula框架解决了,给业务开发者提供了更为简单的Step异步IO。