標籤:des style blog http color 使用
經過的前面的梳理,整個ranch架構的結構,大致有了一個清晰的脈絡,即使我說的不是很清楚大家也基本能閱讀懂源碼。下面我繼續分析剩下的的幾個檔案。
7.ranch_transport.erl
這個檔案是一個自訂的的erlang行為模式,主要規範實現這個行為模式的子類必須要實現那個函數,整個函數分為行為callback的定義,模組函數的定義. 模組函數的實現sendfile. 具體實現了這個行為模式定義的callback的模組有(ranch_tcp.erl,ranch_ssl.erl) 這兩個檔案。看對應的名字都能大致明白什麼功能和作用。這兩個檔案我覺得是整個架構傳輸處理的核心模組。也是把gen_tcp 和ssl 兩種 傳輸協議做了一個統一的對外的介面,便於對整個架構結構的處理。也便於對傳輸協議的擴充。在協議擴充後仍然能再架構下穩定運行起重要作用。假設我們要ranch 支援gen_udp 協議的話 也只需要一個模組使用gen_udp 對整個協議封裝處理即可。ranch_transport 整個回調木塊對網路傳輸塊做了如下的高度抽象。串連,監聽,應答,參數設定,資料接收,發送,檔案發送,斷開,關閉 等介面做了高度抽象的概括。可以說cowboy 從 http 到 https 輕鬆無縫切換,都得益於整個行為模式的抽象處理。
8.ranch_acceptor.erl
start_link(LSocket, Transport, ConnsSup) -> Pid = spawn_link(?MODULE, loop, [LSocket, Transport, ConnsSup]), {ok, Pid}.
首先我們來看看start_link 的幾個參數 第一個參數 串連監聽的socket,第二個參數選擇的傳輸協議 第三個參數串連監督,然後採用連結的方式開啟一個線程。
flush() -> receive Msg -> error_logger:error_msg( "Ranch acceptor received unexpected message: ~p~n",[Msg]), flush() after 0 -> ok end.
這個檔案中為什麼會有flush()這個函數呢?首先這個函數主要是處理接受我們訊息處理中不需要的訊息,把訊息信箱中比如攻擊訊息,等等其餘無用的訊息從訊息信箱中移除,然後再幾率日誌。整個接受過程是一個0逾時處理。如果整個沒有這個重新整理過程的話都存在一些垃圾訊息存在於信箱,導致信箱訊息不停的增大,記憶體不停的增加,最後導致記憶體消耗宕機。
最後我們來看看整個主迴圈
1 loop(LSocket, Transport, ConnsSup) -> 2 _ = case Transport:accept(LSocket, infinity) of 3 {ok, CSocket} -> 4 Transport:controlling_process(CSocket, ConnsSup), 5 %% This call will not return until process has been started 6 %% AND we are below the maximum number of connections. 7 ranch_conns_sup:start_protocol(ConnsSup, CSocket); 8 %% Reduce the accept rate if we run out of file descriptors. 9 %% We can‘t accept anymore anyway, so we might as well wait10 %% a little for the situation to resolve itself.11 {error, emfile} ->12 receive after 100 -> ok end;13 %% We want to crash if the listening socket got closed.14 {error, Reason} when Reason =/= closed ->15 ok16 end,17 flush(),18 ?MODULE:loop(LSocket, Transport, ConnsSup).
整個過程包括三個處理部分:第一步部分對socket accept 等待用戶端串連,如果串連上以後啟動一個串連處理的進程類。第二步清理訊息信箱用無用的垃圾訊息。第三部整個函數尾遞迴調用,繼續等待用戶端串連處理。
明天學習剩下的模組,並對整個零散的思維進行整體的梳理。