關於ejabberd裏面設計gen_iq_handler的理解

上圖是我以前給同事作ejabberd代碼走讀的時候畫的一個消息流圖,當時一個同事問我「ejabberd爲何要設計gen_iq_handler這個模塊?」我當時沒回答出來,讓另一個同事簡單回答了一下。過後我又研究了一下代碼,以爲設計gen_iq_handler的緣由有如下幾個?微信

1:模塊配置裏面有{iqdisc, Value}這一項配置,value的值能夠是no_queue, one_queue, {quques, N}和parallel。gen_iq_handler裏面對不一樣的配置有不一樣的處理代碼,以下:session

add_iq_handler(Component, Host, NS, Module, Function, Type) ->
    case Type of
	no_queue ->
	    Component:register_iq_handler(Host, NS, Module, Function, no_queue);
	one_queue ->
	    {ok, Pid} = supervisor:start_child(ejabberd_iq_sup,
					       [Host, Module, Function]),
	    Component:register_iq_handler(Host, NS, Module, Function,
					  {one_queue, Pid});
	{queues, N} ->
	    Pids =
		lists:map(
		  fun(_) ->
			  {ok, Pid} = supervisor:start_child(
					ejabberd_iq_sup,
					[Host, Module, Function]),
			  Pid
		  end, lists:seq(1, N)),
	    Component:register_iq_handler(Host, NS, Module, Function,
					  {queues, Pids});
	parallel ->
	    Component:register_iq_handler(Host, NS, Module, Function, parallel)
    end.

2:有些IQ結的業務處理很耗時,而有些IQ結的業務處理很快。spa

3:對於耗時的IQ結處理,不能把模塊的iqdisc配置成no_queue,由於若是這樣作的話,由下面面的代碼可知,這條session鏈接就會被阻塞,直到這個IQ結處理完才能繼續處理下一個數據包。設計

handle(Host, Module, Function, Opts, From, To, IQ) ->
    case Opts of
	no_queue ->
	    process_iq(Host, Module, Function, From, To, IQ);
	{one_queue, Pid} ->
	    Pid ! {process_iq, From, To, IQ};
	{queues, Pids} ->
	    Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids),
	    Pid ! {process_iq, From, To, IQ};
	parallel ->
	    spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]);
	_ ->
	    todo
    end.

4:設計gen_iq_handler之後,主業務邏輯不須要直接訪問相應的mod_功能模塊,也就不須要關心這些模塊的配置。主業務邏輯只須要調用gen_iq_handler提供的簡單接口,全部這些功能模塊的配置細節,以及如何根據這些配置細節來調用相應的功能模塊,由gen_iq_handler來處理。gen_iq_handler屏蔽了各模塊的調用差別。code

5:配置成one_queue, {quques, N}和parallel的這些功能模塊,也不須要重複實現gen_server行爲模式,由gen_iq_handler來幫他們實現。這樣作還有一個好處,就是使模塊能夠自由的在no_queue和one_queue, {quques, N}和parallel自由切換,而不須要增長或減小任何代碼,只須要修改配置。server

6:模塊的增減,不須要修改主業務邏輯代碼,只須要增長/減小mod_功能模塊以及修改配置。接口

---------------------------------------------------------hash

歡迎關注個人微信公衆號 ^_^io

相關文章
相關標籤/搜索