本章講解,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
- 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
由於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庫。就這些.......