网狐棋牌(三) 调度引擎初步分析
生活随笔
收集整理的這篇文章主要介紹了
网狐棋牌(三) 调度引擎初步分析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
相關(guān)UML:
CAttempterEngine實(shí)現(xiàn)了兩個(gè)接口:IQueueServiceSink、IAttemperEngine;
通過(guò)前面的分析,偶們了解到,IQueueServiceSink這個(gè)接口被是用來(lái)處理CQueueService中的數(shù)據(jù)的,根據(jù)上面的UML我們可以看到,CAttemperEngine關(guān)聯(lián)了一個(gè)CQueueService(或者直接點(diǎn)說(shuō)是:持有了一個(gè)CQueueService對(duì)象,說(shuō)組合也成)。這樣的話這個(gè)CAttemperEngine暴露出來(lái)的接口就只剩下IAttemperEnging了。
1?//啟動(dòng)服務(wù)
2?virtual?bool?__cdecl StartService();
3?//停止服務(wù)
4?virtual?bool?__cdecl StopService();
5?//設(shè)置網(wǎng)絡(luò)
6?virtual?bool?__cdecl SetSocketEngine(IUnknownEx?*?pIUnknownEx);
7?//注冊(cè)鉤子
8?virtual?bool?__cdecl SetAttemperEngineSink(IUnknownEx?*?pIUnknownEx);
9?//獲取接口
10?virtual?void?*?__cdecl GetQueueService(const?IID?&?Guid, DWORD dwQueryVer);
這個(gè)接口有兩處值得單獨(dú)討論的:SetSocketEngine、GetQueueService;
SetSocketEngine,后面的分析中還會(huì)出現(xiàn),我覺(jué)得這里是一個(gè)設(shè)計(jì)上的失誤導(dǎo)致需要暴露socket引擎接口;
GetQueueService的設(shè)計(jì)思路可能是說(shuō),每個(gè)IAttemperEngine接口背后都有一個(gè)CQueueService,從以后的分析中可以看到,這個(gè)思路是理解整個(gè)kernel的關(guān)鍵。調(diào)度引擎應(yīng)該是一個(gè)消息匯總(從個(gè)個(gè)引擎產(chǎn)生的消息)然后派發(fā)到IAttemperEngineSink。因?yàn)榇a中是沒(méi)有看到有關(guān)ITimerSink? ISocketSink之類(lèi)的東東的,,,
整個(gè)消息是個(gè)引擎產(chǎn)生,然后投遞到指定的CQueueService,然后匯總到這里被派發(fā)到IAttemperEngineSink出去的,,,
看看CAttemperEngine中處理數(shù)據(jù)的代碼:
?1//隊(duì)列接口
?2void?__cdecl?CAttemperEngine::OnQueueServiceSink(WORD?wIdentifier,?void?*?pBuffer,?WORD?wDataSize,?DWORD?dwInsertTime)
?3{
?4????//內(nèi)核事件
?5????ASSERT(m_pIAttemperEngineSink!=NULL);
?6????switch?(wIdentifier)
?7????{
?8????case?EVENT_TIMER:????????????//定時(shí)器事件
?9????????{
10????????????//效驗(yàn)參數(shù)
11????????????ASSERT(wDataSize==sizeof(NTY_TimerEvent));
12????????????if?(wDataSize!=sizeof(NTY_TimerEvent))?return;
13
14????????????//處理消息
15????????????NTY_TimerEvent?*?pTimerEvent=(NTY_TimerEvent?*)pBuffer;
16????????????m_pIAttemperEngineSink->OnEventTimer(pTimerEvent->wTimerID,pTimerEvent->wBindParam);
17
18????????????return;
19????????}
20????case?EVENT_DATABASE:????????//數(shù)據(jù)庫(kù)事件
21????????{
22????????????//效驗(yàn)參數(shù)
23????????????ASSERT(wDataSize>=sizeof(NTY_DataBaseEvent));
24????????????if?(wDataSize<sizeof(NTY_DataBaseEvent))?return;
25
26????????????//處理消息
27????????????NTY_DataBaseEvent?*?pDataBaseEvent=(NTY_DataBaseEvent?*)pBuffer;
28????????????m_pIAttemperEngineSink->OnEventDataBase(pDataBaseEvent+1,wDataSize-sizeof(NTY_DataBaseEvent),pDataBaseEvent);
29
30????????????return;
31????????}
32????case?EVENT_SOCKET_ACCEPT:????//網(wǎng)絡(luò)應(yīng)答事件
33????????{
34????????????//效驗(yàn)大小
35????????????ASSERT(wDataSize==sizeof(NTY_SocketAcceptEvent));
36????????????if?(wDataSize!=sizeof(NTY_SocketAcceptEvent))?return;
37
38????????????//處理消息
39????????????NTY_SocketAcceptEvent?*?pSocketAcceptEvent=(NTY_SocketAcceptEvent?*)pBuffer;
40????????????m_pIAttemperEngineSink->OnEventSocketAccept(pSocketAcceptEvent);
41
42????????????return;
43????????}
44????case?EVENT_SOCKET_READ:????????//網(wǎng)絡(luò)讀取事件
45????????{
46????????????//效驗(yàn)大小
47????????????NTY_SocketReadEvent?*?pSocketReadEvent=(NTY_SocketReadEvent?*)pBuffer;
48????????????ASSERT(wDataSize>=sizeof(NTY_SocketReadEvent));
49????????????ASSERT(wDataSize==(sizeof(NTY_SocketReadEvent)+pSocketReadEvent->wDataSize));
50????????????if?(wDataSize<sizeof(NTY_SocketReadEvent))?return;
51????????????if?(wDataSize!=(sizeof(NTY_SocketReadEvent)+pSocketReadEvent->wDataSize))?return;
52
53????????????//處理消息
54????????????bool?bSuccess=false;
55????????????try?
56????????????{?
57????????????????bSuccess=m_pIAttemperEngineSink->OnEventSocketRead(pSocketReadEvent->Command,pSocketReadEvent+1,pSocketReadEvent->wDataSize,pSocketReadEvent);
58????????????}
59????????????catch?()????{?}
60????????????if?(bSuccess==false)?m_pITCPSocketEngine->CloseSocket(pSocketReadEvent->wIndex,pSocketReadEvent->wRoundID);
61
62????????????return;
63????????}
64????case?EVENT_SOCKET_CLOSE:????//網(wǎng)絡(luò)關(guān)閉事件
65????????{
66????????????//效驗(yàn)大小
67????????????ASSERT(wDataSize==sizeof(NTY_SocketCloseEvent));
68????????????if?(wDataSize!=sizeof(NTY_SocketCloseEvent))?return;
69
70????????????//處理消息
71????????????NTY_SocketCloseEvent?*?pSocketCloseEvent=(NTY_SocketCloseEvent?*)pBuffer;
72????????????m_pIAttemperEngineSink->OnEventSocketClose(pSocketCloseEvent);
73
74????????????return;
75????????}
76????}
77
78????//其他事件
79????m_pIAttemperEngineSink->OnAttemperEvent(wIdentifier,pBuffer,wDataSize,dwInsertTime);?
80
81????return;
82}
這個(gè)函數(shù)中一個(gè)很重要的參數(shù):wIdentifier;
可以來(lái)追溯一下他的源頭:
?1//數(shù)據(jù)消息
?2void?CQueueService::OnQueueServiceThread(const?tagDataHead?&?DataHead,?void?*?pBuffer,?WORD?wDataSize)
?3{
?4????ASSERT(m_pIQueueServiceSink!=NULL);
?5????try????
?6????{?
?7????????m_pIQueueServiceSink->OnQueueServiceSink(DataHead.wIdentifier,pBuffer,DataHead.wDataSize,DataHead.dwInsertTime);?
?8????}
?9????catch?()?{}
10????return;
11} 可以看見(jiàn)他是直接保存在最底層的那個(gè)DataStroage里邊的,這個(gè)在上一章分析中可以看到。(個(gè)引擎利用CQueueServiceEvent? Post數(shù)據(jù)的時(shí)候就攜帶了類(lèi)型信息)
另外一個(gè)要注意的點(diǎn)是對(duì)socket事件的處理,我之前認(rèn)為調(diào)度引擎組合了一個(gè)socket引擎是一個(gè)設(shè)計(jì)缺陷,應(yīng)為這里的在處理socket read事件的時(shí)候如果異常了直接直接使用引擎來(lái)關(guān)閉socket而不是調(diào)用socket sink的指定接口。猜想也許是不希望客戶(hù)端直接處理socket句柄吧,,,
還是用一句話描述下調(diào)度引擎:
CAttempterEngine實(shí)現(xiàn)了兩個(gè)接口:IQueueServiceSink、IAttemperEngine;
通過(guò)前面的分析,偶們了解到,IQueueServiceSink這個(gè)接口被是用來(lái)處理CQueueService中的數(shù)據(jù)的,根據(jù)上面的UML我們可以看到,CAttemperEngine關(guān)聯(lián)了一個(gè)CQueueService(或者直接點(diǎn)說(shuō)是:持有了一個(gè)CQueueService對(duì)象,說(shuō)組合也成)。這樣的話這個(gè)CAttemperEngine暴露出來(lái)的接口就只剩下IAttemperEnging了。
1?//啟動(dòng)服務(wù)
2?virtual?bool?__cdecl StartService();
3?//停止服務(wù)
4?virtual?bool?__cdecl StopService();
5?//設(shè)置網(wǎng)絡(luò)
6?virtual?bool?__cdecl SetSocketEngine(IUnknownEx?*?pIUnknownEx);
7?//注冊(cè)鉤子
8?virtual?bool?__cdecl SetAttemperEngineSink(IUnknownEx?*?pIUnknownEx);
9?//獲取接口
10?virtual?void?*?__cdecl GetQueueService(const?IID?&?Guid, DWORD dwQueryVer);
這個(gè)接口有兩處值得單獨(dú)討論的:SetSocketEngine、GetQueueService;
SetSocketEngine,后面的分析中還會(huì)出現(xiàn),我覺(jué)得這里是一個(gè)設(shè)計(jì)上的失誤導(dǎo)致需要暴露socket引擎接口;
GetQueueService的設(shè)計(jì)思路可能是說(shuō),每個(gè)IAttemperEngine接口背后都有一個(gè)CQueueService,從以后的分析中可以看到,這個(gè)思路是理解整個(gè)kernel的關(guān)鍵。調(diào)度引擎應(yīng)該是一個(gè)消息匯總(從個(gè)個(gè)引擎產(chǎn)生的消息)然后派發(fā)到IAttemperEngineSink。因?yàn)榇a中是沒(méi)有看到有關(guān)ITimerSink? ISocketSink之類(lèi)的東東的,,,
整個(gè)消息是個(gè)引擎產(chǎn)生,然后投遞到指定的CQueueService,然后匯總到這里被派發(fā)到IAttemperEngineSink出去的,,,
看看CAttemperEngine中處理數(shù)據(jù)的代碼:
?1//隊(duì)列接口
?2void?__cdecl?CAttemperEngine::OnQueueServiceSink(WORD?wIdentifier,?void?*?pBuffer,?WORD?wDataSize,?DWORD?dwInsertTime)
?3{
?4????//內(nèi)核事件
?5????ASSERT(m_pIAttemperEngineSink!=NULL);
?6????switch?(wIdentifier)
?7????{
?8????case?EVENT_TIMER:????????????//定時(shí)器事件
?9????????{
10????????????//效驗(yàn)參數(shù)
11????????????ASSERT(wDataSize==sizeof(NTY_TimerEvent));
12????????????if?(wDataSize!=sizeof(NTY_TimerEvent))?return;
13
14????????????//處理消息
15????????????NTY_TimerEvent?*?pTimerEvent=(NTY_TimerEvent?*)pBuffer;
16????????????m_pIAttemperEngineSink->OnEventTimer(pTimerEvent->wTimerID,pTimerEvent->wBindParam);
17
18????????????return;
19????????}
20????case?EVENT_DATABASE:????????//數(shù)據(jù)庫(kù)事件
21????????{
22????????????//效驗(yàn)參數(shù)
23????????????ASSERT(wDataSize>=sizeof(NTY_DataBaseEvent));
24????????????if?(wDataSize<sizeof(NTY_DataBaseEvent))?return;
25
26????????????//處理消息
27????????????NTY_DataBaseEvent?*?pDataBaseEvent=(NTY_DataBaseEvent?*)pBuffer;
28????????????m_pIAttemperEngineSink->OnEventDataBase(pDataBaseEvent+1,wDataSize-sizeof(NTY_DataBaseEvent),pDataBaseEvent);
29
30????????????return;
31????????}
32????case?EVENT_SOCKET_ACCEPT:????//網(wǎng)絡(luò)應(yīng)答事件
33????????{
34????????????//效驗(yàn)大小
35????????????ASSERT(wDataSize==sizeof(NTY_SocketAcceptEvent));
36????????????if?(wDataSize!=sizeof(NTY_SocketAcceptEvent))?return;
37
38????????????//處理消息
39????????????NTY_SocketAcceptEvent?*?pSocketAcceptEvent=(NTY_SocketAcceptEvent?*)pBuffer;
40????????????m_pIAttemperEngineSink->OnEventSocketAccept(pSocketAcceptEvent);
41
42????????????return;
43????????}
44????case?EVENT_SOCKET_READ:????????//網(wǎng)絡(luò)讀取事件
45????????{
46????????????//效驗(yàn)大小
47????????????NTY_SocketReadEvent?*?pSocketReadEvent=(NTY_SocketReadEvent?*)pBuffer;
48????????????ASSERT(wDataSize>=sizeof(NTY_SocketReadEvent));
49????????????ASSERT(wDataSize==(sizeof(NTY_SocketReadEvent)+pSocketReadEvent->wDataSize));
50????????????if?(wDataSize<sizeof(NTY_SocketReadEvent))?return;
51????????????if?(wDataSize!=(sizeof(NTY_SocketReadEvent)+pSocketReadEvent->wDataSize))?return;
52
53????????????//處理消息
54????????????bool?bSuccess=false;
55????????????try?
56????????????{?
57????????????????bSuccess=m_pIAttemperEngineSink->OnEventSocketRead(pSocketReadEvent->Command,pSocketReadEvent+1,pSocketReadEvent->wDataSize,pSocketReadEvent);
58????????????}
59????????????catch?()????{?}
60????????????if?(bSuccess==false)?m_pITCPSocketEngine->CloseSocket(pSocketReadEvent->wIndex,pSocketReadEvent->wRoundID);
61
62????????????return;
63????????}
64????case?EVENT_SOCKET_CLOSE:????//網(wǎng)絡(luò)關(guān)閉事件
65????????{
66????????????//效驗(yàn)大小
67????????????ASSERT(wDataSize==sizeof(NTY_SocketCloseEvent));
68????????????if?(wDataSize!=sizeof(NTY_SocketCloseEvent))?return;
69
70????????????//處理消息
71????????????NTY_SocketCloseEvent?*?pSocketCloseEvent=(NTY_SocketCloseEvent?*)pBuffer;
72????????????m_pIAttemperEngineSink->OnEventSocketClose(pSocketCloseEvent);
73
74????????????return;
75????????}
76????}
77
78????//其他事件
79????m_pIAttemperEngineSink->OnAttemperEvent(wIdentifier,pBuffer,wDataSize,dwInsertTime);?
80
81????return;
82}
這個(gè)函數(shù)中一個(gè)很重要的參數(shù):wIdentifier;
可以來(lái)追溯一下他的源頭:
?1//數(shù)據(jù)消息
?2void?CQueueService::OnQueueServiceThread(const?tagDataHead?&?DataHead,?void?*?pBuffer,?WORD?wDataSize)
?3{
?4????ASSERT(m_pIQueueServiceSink!=NULL);
?5????try????
?6????{?
?7????????m_pIQueueServiceSink->OnQueueServiceSink(DataHead.wIdentifier,pBuffer,DataHead.wDataSize,DataHead.dwInsertTime);?
?8????}
?9????catch?()?{}
10????return;
11} 可以看見(jiàn)他是直接保存在最底層的那個(gè)DataStroage里邊的,這個(gè)在上一章分析中可以看到。(個(gè)引擎利用CQueueServiceEvent? Post數(shù)據(jù)的時(shí)候就攜帶了類(lèi)型信息)
另外一個(gè)要注意的點(diǎn)是對(duì)socket事件的處理,我之前認(rèn)為調(diào)度引擎組合了一個(gè)socket引擎是一個(gè)設(shè)計(jì)缺陷,應(yīng)為這里的在處理socket read事件的時(shí)候如果異常了直接直接使用引擎來(lái)關(guān)閉socket而不是調(diào)用socket sink的指定接口。猜想也許是不希望客戶(hù)端直接處理socket句柄吧,,,
還是用一句話描述下調(diào)度引擎:
調(diào)度引擎的工作可以這樣描述消息匯總、派發(fā)。其他引擎通過(guò)CQueueServiceEvent將消息post到調(diào)度引擎上來(lái)(通過(guò)共享同一個(gè)CQueueService),然后由調(diào)度引擎集中派發(fā)出去,,,
轉(zhuǎn)自:http://www.cppblog.com/Error/articles/147948.html
超強(qiáng)干貨來(lái)襲 云風(fēng)專(zhuān)訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的网狐棋牌(三) 调度引擎初步分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网狐棋牌(二) CQueueServic
- 下一篇: 网狐棋牌(四) TimerEngine