mongodb 異步查詢(續)

  承接前一篇, 服務器採用C編寫, 邏輯層使用LUA, 搭配開源mongodb c driver開發異步查詢接口.


  有了上一次的改造, 這次來說說是如何使用改造後的接口實現異步查詢.


  首先, 再來理清一下思路, 現在的一次完整同步查詢被拆分成3個步驟:

  1.創建併發送請求

 

  2.接受返回結果消息頭

  3.接受返回結果數據並做相應的回調處理

 

   爲此我們需要2個結構來處理這個過程:

    

 

   上圖的第一個結構爲網絡連接內部參數, 用於每次回調處理recv的時候取數據.

   第二個結構爲hash表中的數據, 用每次異步請求ID作爲KEY.

 

   下面會分別對這三個階段進行講解:

請求發送:

   ok, 請求發送時, 首先我們需要爲該次異步請求生成一個query id, 該id可以採用例如UUID類的方法生成, 也可以簡單的使用自增ID.

   其次, 填充本次請求內容, 並將數據庫操作對象保存至hashtbl(query id作key), 將請求發送給DB.

   最後, 將query id返回給LUA邏輯層, 掛起當前coroutine.

 

   C 接口如下:

    

 

   LUA 層接口:

       

 

接收並處理響應:

   這裏面共包含2個部分, 處理消息頭和處理消息數據並打包至邏輯層.

   爲什麼這裏面要把解析頭部和處理數據部分分開, 是因爲頭部長度固定, 我們可以一次讀取完成, 但是後續的數據長度是從頭部信息中獲取

得到的, 我們沒辦法在一開始就確定一共要讀多長的數據, 故要分開處理.

 

   解析頭部: 

      固定讀取定長消息頭, 得到後續數據長度和query id 並得到mongo_reply, 我們需要保存該mongo_reply以便後續處理.

      這裏面我們再次用到了query id, 用其將mongo_reply保存至請求時的hash結構指定KEY中.

 

   處理數據:

      此時由於本次接受到的數據並非一定滿足後續數據長度, 故有可能中斷, 但是好在該次響應在網絡層面上數據是連貫的, 所以我們在讀取

完整響應期間, 可以利用網絡框架幫助我們保存一些臨時參數, 比如保存query id, 這樣即使在非連貫的讀取一次響應數據時也不會因爲

獲取query id而產生不必要的麻煩.

      這樣當我們讀取完整數據後, 就可以封裝結果至邏輯層使用了 :)

 

   接受邏輯:

    

 

   在處理數據時, 再次從hashtbl中獲取了"ns", 寫到這裏, 大家應該明白了爲什麼使用一個hashtbl來保存這個ns, 而不是直接放在網絡框架中

做臨時參數處理, 因爲每次異步請求都會得到ns, 但我們又不能保證每次都是一樣, 請求和響應並非連貫導致了臨時保存的結果可能是錯誤的也

可能是剛剛被置空了... 

 

   封裝結果至LUA邏輯層, 這裏就不列舉代碼了, 簡單說下, 就是將結果保存爲一維線性, 二維hash的lua table中.

   然後調用邏輯層喚醒指定query id的coroutine繼續執行.

 

    

 

 

總結:

   至此, 一個完整的異步查詢請求就編寫完成, 由於時間關係, 代碼層面上還有很多可以精簡優化的餘地,  我在此僅僅作爲提供思路, 歡迎一同探討 :)

email : [email protected]

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章