`
zdx3578
  • 浏览: 96799 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

rabbitmq erlang 源代码读 三 core process启动 gen_server

阅读更多

from http://blog.chinaunix.net/u3/103972/showart.php?id=2130456 这里格式较好
  我原来的博客 zdx3578.cublog.cn

看erlang自己的源代码 proc_lib.erl
proc_info(Pid,Item) when node(Pid) =:= node() ->
    process_info(Pid,Item);
proc_info(Pid,Item) ->
    case lists:member(node(Pid),nodes()) of
    true ->
        check(rpc:call(node(Pid), erlang, process_info, [Pid, Item]));
    _ ->
        hidden
    end.
erlang 把底层远程调用都隐藏了,这就是“显意编程”(intentional programming)吧 http://erlang-china.org/uploads/2007/09/joes-thesis.zip的4.5

gen_server.erl 源代码看看

gen_server.erl  %%从粗体看下去再从斜体看上来
start(Mod, Args, Options) ->
    gen:start(?MODULE, nolink, Mod, Args, Options).
start_link(Mod, Args, Options) ->
    gen:start(?MODULE, link, Mod, Args, Options).
     
gen.erl
start(GenMod, LinkP, Mod, Args, Options) ->
    do_spawn(GenMod, LinkP, Mod, Args, Options).
do_spawn(GenMod, _, Mod, Args, Options) ->
    Time = timeout(Options),
    proc_lib:start(?MODULE, init_it, [GenMod, self(), self, Mod, Args, Options], Time, spawn_opts(Options)). %%MFA
       
proc_lib.erl
-spec start(atom(), atom(), [term()], timeout(), [spawn_option()]) -> term().
start(M, F, A, Timeout, SpawnOpts) when is_atom(M), is_atom(F), is_list(A) ->
    Pid = ?MODULE:spawn_opt(M, F, A, SpawnOpts),
    sync_wait(Pid, Timeout).
spawn_opt(M, F, A, Opts) when is_atom(M), is_atom(F), is_list(A) ->
    Parent = get_my_name(),
    Ancestors = get_ancestors(),
    check_for_monitor(Opts),
    erlang:spawn_opt(?MODULE, init_p, [Parent,Ancestors,M,F,A], Opts).
-spec init_p(pid(), [pid()], atom(), atom(), [term()]) -> term().
init_p(Parent, Ancestors, M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
    put('$ancestors', [Parent|Ancestors]),
    put('$initial_call', trans_init(M, F, A)),
    init_p_do_apply(M, F, A).
init_p_do_apply(M, F, A) ->
    try
    apply(M, F, A)
    catch
    Class:Reason ->
        exit_p(Class, Reason)
    end.

gen.erl的如下语句
    proc_lib:start(?MODULE, init_it, [GenMod, self(), self, Mod, Args, Options], Time, spawn_opts(Options)). %%MFA 就执行gen.erl 的init_it
init_it(GenMod, Starter, Parent, Mod, Args, Options) ->%%FA
    init_it2(GenMod, Starter, Parent, self(), Mod, Args, Options).
  
init_it2(GenMod, Starter, Parent, Name, Mod, Args, Options) ->
    GenMod:init_it(Starter, Parent, Name, Mod, Args, Options).%%A GenMod 就是gen_server,执行gen_server的init

gen_server.erl
init_it(Starter, self, Name, Mod, Args, Options) ->
    init_it(Starter, self(), Name, Mod, Args, Options);
init_it(Starter, Parent, Name0, Mod, Args, Options) ->
    Name = name(Name0),
    Debug = debug_options(Name, Options),
    case catch Mod:init(Args) of                    %%gen_server 在调用Mod模块的init
    {ok, State} ->
        proc_lib:init_ack(Starter, {ok, self()}),       
        loop(Parent, Name, State, Mod, infinity, Debug);%%开始循环
    {ok, State, Timeout} ->
        proc_lib:init_ack(Starter, {ok, self()}),       
        loop(Parent, Name, State, Mod, Timeout, Debug);
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
    end.


%%% The MAIN loop.
%%% ---------------------------------------------------
loop(Parent, Name, State, Mod, hibernate, Debug) ->
    proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, Debug]);
loop(Parent, Name, State, Mod, Time, Debug) ->
    Msg = receive
          Input ->
            Input
      after Time ->
          timeout
      end,
    decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, false).

decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) ->
    case Msg of
    {system, From, Req} ->
        sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
                  [Name, State, Mod, Time], Hib);
    {'EXIT', Parent, Reason} ->
        terminate(Reason, Name, Msg, Mod, State, Debug);
    _Msg when Debug =:= [] ->
        handle_msg(Msg, Parent, Name, State, Mod);
    _Msg ->
        Debug1 = sys:handle_debug(Debug, {?MODULE, print_event},
                      Name, {in, Msg}),
        handle_msg(Msg, Parent, Name, State, Mod, Debug1)
    end.

%%% Message handling functions
%%% ---------------------------------------------------

dispatch({'$gen_cast', Msg}, Mod, State) ->
    Mod:handle_cast(Msg, State);
dispatch(Info, Mod, State) ->
    Mod:handle_info(Info, State).

handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
    case catch Mod:handle_call(Msg, From, State) of    %%回调handle_call
    {reply, Reply, NState} ->
        reply(From, Reply),
        loop(Parent, Name, NState, Mod, infinity, []);   %%继续循环
    {reply, Reply, NState, Time1} ->
        reply(From, Reply),
        loop(Parent, Name, NState, Mod, Time1, []);
    {noreply, NState} ->
        loop(Parent, Name, NState, Mod, infinity, []);
    {noreply, NState, Time1} ->
        loop(Parent, Name, NState, Mod, Time1, []);
    {stop, Reason, Reply, NState} ->
        {'EXIT', R} =
        (catch terminate(Reason, Name, Msg, Mod, NState, [])),
        reply(From, Reply),
        exit(R);
    Other -> handle_common_reply(Other, Parent, Name, Msg, Mod, State)
    end;
handle_msg(Msg, Parent, Name, State, Mod) ->
    Reply = (catch dispatch(Msg, Mod, State)),
    handle_common_reply(Reply, Parent, Name, Msg, Mod, State).









——————————————————————————————————————————————————————————————


rabbit.erl
start(normal, []) ->
    {ok, SupPid} = rabbit_sup:start_link(),

rabbit_sup.erl
-define(SERVER, ?MODULE).
start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).%%注册supervisor name {local,rabbit_sup}

init([]) ->
    {ok, {{one_for_one, 10, 10}, []}}.
  
rabbit.erl
       {"core processes",
        fun () ->
                ok = start_child(rabbit_log),
                ok = rabbit_hooks:start(),

                ok = rabbit_binary_generator:
                    check_empty_content_body_frame_size(),
                {ok, MemoryAlarms} = application:get_env(memory_alarms),
                ok = rabbit_alarm:start(MemoryAlarms),
                ok = rabbit_amqqueue:start(),
                ok = start_child(rabbit_router),
                ok = start_child(rabbit_node_monitor)
        end},


start_child(Mod) ->
    {ok,_} = supervisor:start_child(rabbit_sup,%%这个名的注册就是在start/2启动时的rabbit_sup:start_link() 启动的
                                    {Mod, {Mod, start_link, []},
                                     transient, 100, worker, [Mod]}),
    ok.


supervisor.erl:
-behaviour(gen_server).
start_child(Supervisor, ChildSpec) ->
    call(Supervisor, {start_child, ChildSpec}).
call(Supervisor, Req) ->
    gen_server:call(Supervisor, Req, infinity).
  
gen_server.erl
call(Name, Request, Timeout) ->
    case catch gen:call(Name, '$gen_call', Request, Timeout) of
    {ok,Res} ->
        Res;
    {'EXIT',Reason} ->
        exit({Reason, {?MODULE, call, [Name, Request, Timeout]}})
    end.
  
  
gen.erl
call(Pid, Label, Request, Timeout)
  when is_pid(Pid), Timeout =:= infinity;
       is_pid(Pid), is_integer(Timeout), Timeout >= 0 ->
    do_call(Pid, Label, Request, Timeout);  

do_call(Process, Label, Request, Timeout) ->
    Node = case Process of
            {_S, N} when is_atom(N) ->
            N;
            _ when is_pid(Process) ->
            node(Process)
       end,
    try erlang:monitor(process, Process) of
    Mref ->
        catch erlang:send(Process, {Label, {self(), Mref}, Request},
          [noconnect]),
        wait_resp_mon(Node, Mref, Timeout)
    catch
    error:_ ->
        monitor_node(Node, true),
        receive
        {nodedown, Node} ->
            monitor_node(Node, false),
            exit({nodedown, Node})
        after 0 ->
            Tag = make_ref(),
            Process ! {Label, {self(), Tag}, Request},
            wait_resp(Node, Tag, Timeout)
        end
    end.

wait_resp_mon(Node, Mref, Timeout) ->
..............

wait_resp(Node, Tag, Timeout) ->
..............

gen_server.erl
dispatch({'$gen_cast', Msg}, Mod, State) ->
    Mod:handle_cast(Msg, State);
dispatch(Info, Mod, State) ->
    Mod:handle_info(Info, State).

handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod) ->
    case catch Mod:handle_call(Msg, From, State) of
    {reply, Reply, NState} ->
        reply(From, Reply),
        loop(Parent, Name, NState, Mod, infinity, []);
    {reply, Reply, NState, Time1} ->
        reply(From, Reply),
        loop(Parent, Name, NState, Mod, Time1, []);
    {noreply, NState} ->
        loop(Parent, Name, NState, Mod, infinity, []);
    {noreply, NState, Time1} ->
        loop(Parent, Name, NState, Mod, Time1, []);
    {stop, Reason, Reply, NState} ->
        {'EXIT', R} =
        (catch terminate(Reason, Name, Msg, Mod, NState, [])),
        reply(From, Reply),
        exit(R);
    Other -> handle_common_reply(Other, Parent, Name, Msg, Mod, State)
    end;
handle_msg(Msg, Parent, Name, State, Mod) ->
    Reply = (catch dispatch(Msg, Mod, State)),
    handle_common_reply(Reply, Parent, Name, Msg, Mod, State).
  
handle_common_reply(Reply, Parent, Name, Msg, Mod, State) ->
    case Reply of
    {noreply, NState} ->
        loop(Parent, Name, NState, Mod, infinity, []);
    {noreply, NState, Time1} ->
        loop(Parent, Name, NState, Mod, Time1, []);
    {stop, Reason, NState} ->
        terminate(Reason, Name, Msg, Mod, NState, []);
    {'EXIT', What} ->
        terminate(What, Name, Msg, Mod, State, []);
    _ ->
        terminate({bad_return_value, Reply}, Name, Msg, Mod, State, [])
    end.


  
  
supervisor.erl:
handle_call({start_child, ChildSpec}, _From, State) ->
    case check_childspec(ChildSpec) of
    {ok, Child} ->
        {Resp, NState} = handle_start_child(Child, State),
        {reply, Resp, NState};
    What ->
        {reply, {error, What}, State}
    end;

分享到:
评论
2 楼 zdx3578 2010-03-01  
不好意思,博客还在老地方  zdx3578.cublog.cn
1 楼 mryufeng 2010-03-01  
rabbitmq是个很好的code example

相关推荐

    erlang21.2 和 rabbitmq_server-3.7.13

    OTP_src_21.2 是Erlang 21.2 版本的源代码包,开发者可以借此深入了解Erlang的内部工作原理,并对系统进行自定义和扩展。此版本可能包括性能优化、新的API、错误修复以及其他改进,以增强Erlang平台的稳定性和效率。...

    Java开发案例-springboot-06-整合RabbitMQ-源代码+文档.rar

    Java开发案例-springboot-06-整合RabbitMQ-源代码+文档.rar Java开发案例-springboot-06-整合RabbitMQ-源代码+文档.rar Java开发案例-springboot-06-整合RabbitMQ-源代码+文档.rar Java开发案例-springboot-06-整合...

    Erlang和RabbitMQ安装包

    Erlang是一种函数式编程语言,以其并发性、容错性和热代码升级能力而闻名,而RabbitMQ则是基于Erlang构建的一个开源消息代理,用于实现应用程序之间的异步通信。 **Erlang** Erlang由瑞典电信设备制造商Ericsson...

    最新最全rabbitmq与erlang版本匹配-2020-04-23.docx

    **RabbitMQ与Erlang版本匹配指南** RabbitMQ是一种广泛使用的开源消息代理和队列服务器,它基于Erlang编程语言构建。Erlang以其并发能力、容错性和分布式特性而闻名,是实现RabbitMQ的理想选择。正确地匹配RabbitMQ...

    rabbitMq和erlang安装包

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统。它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rabbit MQ 是建立在Erlang OTP平台上。

    Rabbitmq_server_3.10.7安装包

    Rabbitmq_server_3.10.7安装包

    rabbitmq-erlang-安装包-整体安装包.zip

    标题中的“rabbitmq-erlang-安装包-整体安装包.zip”表明这是一份包含RabbitMQ和Erlang的整体安装包,用于在特定的操作系统环境下(可能是基于Red Hat Enterprise Linux 7)进行安装。RabbitMQ是一个开源的消息代理...

    rabbitmq3.8.4 和 erlang23.0

    压缩包包含有 rabbitmq3.8.4 和 erlang23.0,亲测可用。 1. erlang安装配置: Windows版下载地址:http://www.erlang.org/downloads, 打开后选择最新的下载即可,需要注意的是你的系统是32位还是64位的就可以了。...

    rabbitmq + Erlang

    安装好Erlang和RabbitMQ后,你可以通过命令行工具启动RabbitMQ服务器,并使用管理界面来管理队列、交换机和绑定。RabbitMQ支持多种编程语言的客户端库,使得开发者可以轻松地在各种应用中集成消息队列功能。例如,你...

    RabbitMQ Erlang 安装包与使用说明

    对于 otp_src_19.2.tar.gz 文件,这代表了Erlang的源代码包。你需要进行以下步骤: 1. 解压文件:`tar -xvf otp_src_19.2.tar.gz` 2. 进入解压后的目录:`cd otp_src_19.2` 3. 配置、编译并安装Erlang:`./configure...

    rabbitmq+erlang.rar

    Erlang的特点在于其轻量级进程、热代码替换、以及内置的错误恢复机制,这些特性使得Erlang特别适合构建大规模、高并发的网络服务。在RabbitMQ中,Erlang的语言特性保证了服务器能够处理大量并发连接,并且在节点故障...

    RabbitMQ+erlang安装包

    Erlang是一种并发性极强的编程语言,RabbitMQ就是用Erlang编写的,因此在安装RabbitMQ之前,必须先安装Erlang运行环境。 Erlang 21.1是RabbitMQ 3.7.8版本所依赖的特定版本,这是因为不同的RabbitMQ版本可能与不同...

    esl-erlang_23.0_windows_amd64.exe rabbitmq-server-3.8.4.exe

    esl-erlang_23.0和rabbitmq-3.8.4windows版本 直接下载安装就行,可以直接下载就可安装,非常的方便 ,欢迎大家下载 注意事项: 1. Erlang版本和RabbitMQ版本要配套 (Erlang23.0, RabbitMQ3.8.4) 2. amd芯片请乖乖...

    Erlang22.2和RabbitMQ3.8.2安装包(Windows64位)

    otp_win64_22.2.exe ...rabbitmq-server-3.8.2.exe windows64位下 欢迎下载 官网地址: Erlang:https://www.erlang.org/downloads RabbitMQ:https://www.rabbitmq.com/install-windows.html

    RabbitMQ+erlang.zip

    **RabbitMQ与Erlang:构建高效的消息队列系统** 在IT行业中,RabbitMQ是一种广泛使用的开源消息代理和队列服务器,它基于AMQP(Advanced Message Queuing Protocol)协议,提供了一种可靠且可扩展的方式来处理应用...

    erlang20.3+rabbitmq server.rar

    标题中的"erlang20.3+rabbitmq server.rar"表明这是一个包含Erlang OTP版本20.3和RabbitMQ服务器的压缩包,专为在Windows操作系统上部署RabbitMQ设计。Erlang是一种并发性极强的编程语言,主要用于构建高可用性和...

    rabbitmq erlang otp-win64-26.0.1.exe

    rabbitmq erlang otp_win64_26.0.1.exe windows版本,以管理员安装

    rabbitmq3.3.7 +erlang_21.0.1

    4. **启动和管理RabbitMQ**:使用`rabbitmq-server`命令启动服务,并使用`rabbitmqctl`工具进行管理,如查看状态、添加用户、创建虚拟主机等。 5. **配置安全**:为了防止未授权访问,应创建用户并限制其访问权限,...

    rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,

    rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang,rabbitmq和erlang

    RabbitMQ+erlang

    - **热代码替换**:Erlang支持在运行时更新和升级代码,无需重启服务,这在RabbitMQ中用于在线维护和升级。 - **容错性**:Erlang虚拟机(BEAM)允许错误隔离,即使部分节点故障,整个系统仍能继续运行。 ### 2. ...

Global site tag (gtag.js) - Google Analytics