skynet框架 源码分析 五

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

       说说各自的作用。

       mqueue库:

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

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

local function dispatch_message(...)
	local succ, err = pcall(raw_dispatch_message,...)
	while true do
		local key,co = next(fork_queue)
		if co == nil then
			break
		end
		fork_queue[key] = nil
		local fork_succ, fork_err = pcall(suspend,co,coroutine.resume(co))
		if not fork_succ then
			if succ then
				succ = false
				err = fork_err
			else
				err = err .. "\n" .. fork_err
			end
		end
	end
	assert(succ, err)
end
              在通过取出fork_queue中的元素执行message_dispatch逻辑。这里面有一个有趣的逻辑。即,当从fork_queue中取出该协程后,forkqueue中该协程被弹出。也就是说,下次不会在fork_queue中再找到该message_dispatch协程。在执行完raw_dispatch_message后,不会在fork_queue中启动message_dispatch逻辑。那会在哪里启动该逻辑呢?看看message_dispatch逻辑。
local function message_dispatch(f)
	while true do
		if #message_queue==0 then
			thread_id = coroutine.running()
			skynet.wait()
		else
			local msg = table.remove(message_queue,1)
			local session = msg.session
			if session == 0 then
				if do_func(f, msg) ~= nil then
					skynet.fork(message_dispatch,f)
					error(string.format("[:%x] send a message to [:%x] return something", msg.addr, skynet.self()))
				end
			else
				local data, size = skynet.pack(do_func(f,msg))
				-- 1 means response
				c.send(msg.addr, 1, session, data, size)
			end
		end
	end
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库。就这些.......








阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页