P2Psim分析筆記(7)-RPC機制

技術小胖子發表於2017-11-09
    這是分析筆記的最後一篇,這篇介紹了p2p模擬中最常用的RPC機制在P2Psim中的實現。這篇對P2Psim的模擬機制的最後一部分進行了說明。P2Psim中,不同的P2P協議實現都是基於這個機制來模擬peer間的通訊。
    RPC(Remote Procedure call)的本意是,一臺電腦通過網路來來執行另外一臺電腦上的函式,函式執行的結果再送回本機。這個機制有很多實現和變形,比如xmlrpc, Soap, 我在這裡不扯開了,大家google一下就知道了。因此按照RPC的概念,P2P中peer之間的相互訪問都可以看作是RPC操作。因此在P2P的模擬中,模擬軟體都不約而同實現一套簡化了的rpc介面,這樣在應用層的p2p協議只要用這套介面就可以不必理會底層網路通訊的細節了。這篇中我給出了RPC實現的說明圖。
    圖中,不同p2p協議通過呼叫Node中的doRPC()和asyncRPC()來傳送資料給遠端的peer。前者是同步的,也就是說,在沒收到對方peer的回覆或者超時前,本peer就一直死等。後者是非同步的rpc呼叫。在非同步的方式下,peer呼叫asyncRPC()函式會立刻得到返回,然後協議得到一個該次請求的控制程式碼,可以理解成取貨憑證。然後peer隔一段時間在通過rcvRPC()函式,用這個控制程式碼來查詢一下,這個遠端呼叫是不是返回結果了,或者失敗了(比如網路丟包)。這好比拿著取貨憑證去取貨一樣。同樣如果這個peer收到別人傳送來的rpc請求,他也要提供處理相應請求的處理函式。當收到這個請求的時候,相應處理函式被呼叫。關於請求,我們遲點再分析。我們先逐個分析doRPC()和asyncRPC()的實現。
    當Protocol類的物件呼叫了Node類中的doRPC()時,Node類首先通過_maktrunk函式把這個請求打包(為了更像一個網路報文?不知道),然後依次呼叫_doRPC_send()函式在這個報文上面加一個channel(libtask裡面的多工間的資料通訊機制)把這個請求的trunk發給Network類的send()介面。Network根據拓撲算出這個報文到達對方peer的延遲,然後生成一個NetEvent事件放入事件佇列裡。當doRPC()傳送了這個資料包後,立刻呼叫_doRPC_receve()來在這個報文的等待這個資料包上的channel上是否有資料過來,如果有,則從channel中取出這個rpc是否成功的資訊再依次返回給doRPC()函式和上層的呼叫程式碼。如果成功,這個rpc請求中的返回值指標指向的資料結構已經被對方peer給改寫了。以這種方式模擬rpc結果資料的返回。
    當Protocol類的物件呼叫了Node類中的asyncRPC()介面的時候,機制稍微不同一點。asyncRPC同樣呼叫_maktrunk()封裝出一個trunk包,然後讓_doRPC_send()函式傳送出這個包,但是返回的rpc控制程式碼(取貨憑證)被存放到_rpcmap結構中暫時儲存起來。然後asnycRPC()函式就立刻返回這個控制程式碼給上層protocol的呼叫程式碼了。然後呢,上層程式碼在之後的事件裡面可以時不時通過rcvRPC()介面來查詢一下_rpcmap結構裡面這個憑條對應的請求有沒有得到響應或者是否出錯了。
   以上講完了rpc請求傳送的基本邏輯流程,接下來說一下rpc請求被接收的流程。上篇我說了,當EventQueue處理NetEvent事件的時候呼叫其execute()會導致Node中的Packet_handler()介面被呼叫。這個介面函式會區分,該訊息對應的是rpc請求還是rpc應答。如果是應答的話,他就這個報文通過其channel(記得在_doRPC_send()中建立的channel麼?)傳送過去。 如果_doRPC_receive()正在等待channel上的資料,這個資料就會讓_doRPC_receive()返回,完成同步RPC。如果這是一個非同步的rpc,無所謂,這個資料就存在channel裡面了,等peer呼叫rcvRPC()去查詢和收取。
  如果這是一個請求事件,那Packet_handler()就建立一個新task來執行receive()函式。這個函式中,這個事件中rpc的請求型別會被拿出來分析,對應不同的事件型別,protocol裡面的不同事件處理函式會被呼叫。也就是說Protocol物件例項中的相應RPC處理函式“被”執行了。根據執行結果,receive()函式構造出RPC響應資料包,然後再通過Network類的send()結構最終又變成NetEvent事件插入到事件佇列EventQueue裡面去了。至於RPC的響應如何處理,上一段已經說過了。
 
無命名
     本文轉自nathanxu 51CTO部落格,原文連結:http://blog.51cto.com/nathanxu/250585,如需轉載請自行聯絡原作者


相關文章