[erlang] 什么是supervisor_bridge

news/2024/7/2 5:14:52

在OTP的源代码中,我发现了一个陌生的behaviour,名为supervisor_bridge。它的作用是什么,和普通的supervisor又有什么区别呢?

于是我找到了supervisor_bridge.erl这个文件。

首先它是一个gen_server.

-module(supervisor_bridge).

-behaviour(gen_server).

-include("logger.hrl").

%% External exports
-export([start_link/2, start_link/3]).
%% Internal exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).
-export([code_change/3]).

这个behaviour只有两个回调,描述其如何启动,如何终止。

-callback init(Args :: term()) ->
    {ok, Pid :: pid(), State :: term()} | ignore | {error, Error :: term()}.
-callback terminate(Reason :: (shutdown | term()), State :: term()) ->
    Ignored :: term().

发现了这样一段注释,大意是这个模块的功能是当其作为supervisor时,启动和终止子进程都是调用特定的模块中自定义的函数,而不是系统默认的。

%%% This module is built to function as process code
%%% for a process sitting inbetween a real supervisor
%%% and a not start&recovery complient server/system
%%% The process inbetween simulates start&recovery
%%% behaviour of the server/system below.

启动时,会调用特定模块中的启动函数,并link到对应的进程。

init([Mod, StartArgs, Name0]) ->  
    process_flag(trap_exit, true),
    Name = supname(Name0, Mod),
    case Mod:init(StartArgs) of
    {ok, Pid, ChildState} when is_pid(Pid) ->
        link(Pid),
        report_progress(Pid, Mod, StartArgs, Name),
        {ok, #state{mod = Mod, pid = Pid,
            child_state = ChildState, name = Name}};
    ignore ->
        ignore;
    {error, Reason} ->
        {stop, Reason}
    end.

supname(self, Mod) -> {self(),Mod};
supname(N, _)      -> N.

子进程退出后,并不会重启,而是直接退出。

handle_info({'EXIT', Pid, Reason}, State) when State#state.pid =:= Pid ->
    case Reason of
    normal ->
        ok;
    shutdown ->
        ok;
    {shutdown, _Term} ->
        ok;
    _ ->
        report_error(child_terminated, Reason, State)
    end,
    {stop, Reason, State#state{pid = undefined}};

主动终结,调用对应模块中的终结函数来结束子进程。

terminate(_Reason, #state{pid = undefined}) ->
    ok;
terminate(Reason, State) ->
    terminate_pid(Reason, State).
    
...

%% This function is supposed to terminate the 'real' server.
terminate_pid(Reason, #state{mod = Mod, child_state = ChildState}) ->
    Mod:terminate(Reason, ChildState).

当使用supervisor_bridge的时候,对应的子进程是否真的启动或者终结了,还是在进行一些别的操作,都可以根据需求自定义。在外界看来,它们的行为和普通的supervisor、worker无异。


http://www.niftyadmin.cn/n/2868290.html

相关文章

C#中的数据类型(1)

C#中的数据类型(1) C#中的数据类型(1)C#中的数据可以分为两大类:值类型(Value Type)和引用类型(Reference Type)。值类型的对象,继承自System.ValueType类(此类的对象却是引用类型的&#xff09…

电商发展迅速 消费者享便利- 从网购演变 看大数据运用

“没抢上”、“付不了款”、“折后价比折前还高”……许多人忙着吐槽“双十一”时,“38分钟28秒天猫交易额已突破100亿”。  “双十一”的消费数字无疑再次聚焦世人目光。的确,从整个中国网购的演变上看,电子商务呈逐年上升趋势&#xff0c…

10063---java多线程总结五:线程池的原理及实现

原文 1、线程池简介: 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在…

卡方检验的自由度

为什么80%的码农都做不了架构师?>>> 自由度:取值不受限制的变量的个数。 如何理解这句简单的话呢?给定一组数据,我们来计算不同的统计量,看看自由度的变化。这些数据分别为 1 2 4 6 8. 5个数。 先来求平均…

大数据里挖掘大商机

“身处阿里巴巴总部的数据直播中心,仿佛来到航天基地观摩火箭发射。”一位参加过现场报道的媒体同行曾向记者这样描述。 作为最受消费者关注的年度盛事之一,11月10日至11日,来自海内外的460多家媒体守候在阿里巴巴西溪园区,捕捉着…

10065---【Java多线程】线程池的工作原理详解(上)

原文 为什么使用线程池 线程池为线程生命周期开销问题和资源不足问题提供了解决方案,因为线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监…

使用vue-meta进行mate动态管理HTML head信息

vue-meta的官方文档在这里。文档中比较详细地说明了在浏览器端和服务器端如何使用 vue-meta 修改页面头部信息,这里我主要介绍下在SPA项目中管理meta info的使用方法。, vue单页运用中,对单独页面使用meta的时候,他不是直接修改&a…

大数据会带来越来越细的标准

我们经常谈大数据,什么是大数据呢?大数据首先它体积非常大,有各种各样的数据,另外还有非常复杂,还包括数据传输的速度。在2000年的时候,我们的因特网的大小规模大概21Tb,用现在的技术&#xff0…