skynet框架 源码分析 五

 本章讲解,skynet的队列服务。
       队列服务在源码中涉及skynet脚本库,mqueue脚本库,pingqueue测试服务,pingserver测试服务。

       说说各自的作用。

       mqueue库:

              1、封装一个queue消息发送的api==>mqueue.call。

              2、注册一个queue消息处理函数(message_dispatch)。message_disspatch是在skynet脚本库的dispatch_message执行完毕后再执行的。如下:

[plain]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. local function dispatch_message(...)  
  2.     local succ, err = pcall(raw_dispatch_message,...)  
  3.     while true do  
  4.         local key,co = next(fork_queue)  
  5.         if co == nil then  
  6.             break  
  7.         end  
  8.         fork_queue[key] = nil  
  9.         local fork_succ, fork_err = pcall(suspend,co,coroutine.resume(co))  
  10.         if not fork_succ then  
  11.             if succ then  
  12.                 succ = false  
  13.                 err = fork_err  
  14.             else  
  15.                 err = err .. "\n" .. fork_err  
  16.             end  
  17.         end  
  18.     end  
  19.     assert(succ, err)  
  20. end  
              在通过取出fork_queue中的元素执行message_dispatch逻辑。这里面有一个有趣的逻辑。即,当从fork_queue中取出该协程后,forkqueue中该协程被弹出。也就是说,下次不会在fork_queue中再找到该message_dispatch协程。在执行完raw_dispatch_message后,不会在fork_queue中启动message_dispatch逻辑。那会在哪里启动该逻辑呢?看看message_dispatch逻辑。
[plain]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. local function message_dispatch(f)  
  2.     while true do  
  3.         if #message_queue==0 then  
  4.             thread_id = coroutine.running()  
  5.             skynet.wait()  
  6.         else  
  7.             local msg = table.remove(message_queue,1)  
  8.             local session = msg.session  
  9.             if session == 0 then  
  10.                 if do_func(f, msg) ~= nil then  
  11.                     skynet.fork(message_dispatch,f)  
  12.                     error(string.format("[:%x] send a message to [:%x] return something", msg.addr, skynet.self()))  
  13.                 end  
  14.             else  
  15.                 local data, size = skynet.pack(do_func(f,msg))  
  16.                 -- 1 means response  
  17.                 c.send(msg.addr, 1, session, data, size)  
  18.             end  
  19.         end  
  20.     end  
  21. end  
              有一个关键接口:skynet.wait,让当前协程以sleep的状态保留在当前服务中,并切出协程回到lua主线程。每次skynet库在执行suspend后会调用dispatch_wakeup接口。若,该协程在wakeup_session中被标志了true,那么在dispatch_wakeup中,会重新启动message_dispatch协程。

              由于message_dispatch中有一个循环体,所以,在没有return,break关键字的正常情况下,该服务中的message_dispatch接口会一直执行下去。message_dispatch每次会从message_queue表中取一个元素,执行一次逻辑。

              3、注册一个queue消息队列添加函数(dispatch)。将新到的queue消息添加到message_queue表中。

       pingqueue服务:

              1、作为一个消息队列服务,按顺序调用队列中的服务。意思就是,向该服务发送的所有queue消息,都以先进先出的方式处理。该服务中调用了mqueue.register,注册了一个message_dispatch回调在fork_queue。该服务负责排序。

       pingserver服务:

              1、响应消息的服务。被太多用途。

       

       说了这么多,谈谈实战。
       什么情况下会用到这种类型的服务呢?
       目前还没想好,想好了添上去..................先吃饭........

       

2014-3-26 补充:

        本来想再写一篇续,来继续本文所说的mqueue用法。不过,整个设计完善的差不多的时候发现,mqueue库只是其中的基础组件。所以就在这里补充说几句。

        我打算在我的登入排队系统中使用mqueue库。就这些.......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值