Cindy 3.0a5 released
- 修正ant脚本中未使用fork加载http server的bug
- 将内部BufferCache接口改名为BufferPool
- 在Session接口中,使用getAttribute/setAttribute/removeAttribute代替原来的getAttachment/setAttachment方法(谢谢wei_cheng和Arbow)
- 提高了DefaultBufferPool的实现效率,分配和释放时根据Buffer大小使用不同的锁
- 重新设计了SessionAcceptor接口,统一了原来的SocketSessionAcceptor和ServerSocketChannelSession
- 修正了AbstractChannelSession中的分发事件顺序可能不一致的Bug
- 为ServerSocketChannelSession添加了多次accept行为
- 添加了acceptor/session.socketSession/session.datagramSession的运行期配置
- 重载了AbstractBuffer类的equals方法
- 一些小的改进
比较重要的几点改进:
- 为ServerSocketChannelSession添加了多次accept行为。原来是触发了OP_ACCEPT后只accept一次,然 后继续监听OP_ACCEPT;而现在则是触发了OP_ACCEPT后一直accept,直到accept返回为null,再继续监听 OP_ACCEPT。加入这一行为后,在未达到临界点前,系统的性能大约提高了10%左右。可参考HP上的一篇文档:Exploring the Performance of Select-based Internet Servers
- 重新设计了SessionAcceptor接口,统一了原来的SocketSessionAcceptor和 ServerSocketChannelSession两种不同的模型。应用不再需要循环accept了,在默认情况下使用 NonBlockingSessionAcceptor(即相当于Cindy 3.0a4版中基于session的acceptor),性能比原来有所提升。具体改进可见cindy中的示例代码。
- 修正了AbstractChannelSession中的分发事件顺序可能不一致的Bug。分发事件顺序的Bug一直在修正,老是解决了老问题后又发现了新问题:(,不过目前看来新问题出现的越来越少了:)
比如如下代码:
startFuture.setSucceed(true);
getSessionFilterChain(false).sessionStarted();
第一行代码使得Future完成事件被触发,第二行代码使得SessionFilterChain上的sessionStarted事件被触发。看上去没有任何问题,是吗?
可是,如果加入这么一个FutureListener:
startFuture.addFutureListener(new FutureListener() {
public void futureCompleted(...) {
session.close();
}
});
在使用DirectDispatcher的情况下,事件的触发顺序就变成了: Start future completed(上面的第一行代码) --> session close --> session closed --> session started(上面的第二行代码),出现了明显的错误。
所以这次Cindy 3.0a5中把所有这种顺序派发的事件全部改在Dispatcher内完成,比如上面的代码就改成了:
// keep dispatch order
dispatch(new Runnable() {
public void run() {
startFuture.setSucceeded(true);
getSessionFilterChain(false).sessionStarted();
}
});
可以参考DirectDispatcher中的代码,就能了解为什么这么做就能保持事件分发顺序。