接上ranch 源码分析(一)

上次讲到了ranch.erl的start_listener函数,下面我们详细分析下这个函数

-module(ranch).

%...... 省略若干行

-spec start_listener(ref(), non_neg_integer(), module(), any(), module(), any())
-> supervisor:startchild_ret().
start_listener(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
when is_integer(NbAcceptors) andalso is_atom(Transport)
andalso is_atom(Protocol) ->
_ = code:ensure_loaded(Transport),
%% @todo Remove in Ranch 2.0 and simply require ssl.
_ = ensure_ssl(Transport),
case erlang:function_exported(Transport, name, 0) of
false ->
{error, badarg};
true ->
Res = supervisor:start_child(ranch_sup, child_spec(Ref, NbAcceptors,
Transport, TransOpts, Protocol, ProtoOpts)),
Socket = proplists:get_value(socket, TransOpts),
case Res of
{ok, Pid} when Socket =/= undefined ->
%% Give ownership of the socket to ranch_acceptors_sup
%% to make sure the socket stays open as long as the
%% listener is alive. If the socket closes however there
%% will be no way to recover because we don't know how
%% to open it again.
Children = supervisor:which_children(Pid),
{_, AcceptorsSup, _, _}
= lists:keyfind(ranch_acceptors_sup, 1, Children),
%%% Note: the catch is here because SSL crashes when you change
%%% the controlling process of a listen socket because of a bug.
%%% The bug will be fixed in R16.
catch Transport:controlling_process(Socket, AcceptorsSup);
_ ->
ok
end,
Res
end. %...... 省略若干行 -spec child_spec(ref(), non_neg_integer(), module(), any(), module(), any())
-> supervisor:child_spec().
child_spec(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts)
when is_integer(NbAcceptors) andalso is_atom(Transport)
andalso is_atom(Protocol) ->
%% @todo Remove in Ranch 2.0 and simply require ssl.
_ = ensure_ssl(Transport),
{{ranch_listener_sup, Ref}, {ranch_listener_sup, start_link, [
Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts
]}, permanent, infinity, supervisor, [ranch_listener_sup]}. %...... 省略若干行

可以看到在ranch的start_listener中,首先查看Transport模块(传输层模块,这里是ranch_tcp)是否载入,

如果正常载入就启动ranch_listener_sup:start_link/6为ranch_sup的子进程

supervisor:start_child不明白的可以参考 [Erlang 0030] 理解Erlang/OTP Supervisor

下面我们查看ranch_listener_sup.erl

-module(ranch_listener_sup).
-behaviour(supervisor). -export([start_link/6]).
-export([init/1]). -spec start_link(ranch:ref(), non_neg_integer(), module(), any(), module(), any())
-> {ok, pid()}.
start_link(Ref, NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts) ->
MaxConns = proplists:get_value(max_connections, TransOpts, 1024),
ranch_server:set_new_listener_opts(Ref, MaxConns, ProtoOpts),
supervisor:start_link(?MODULE, {
Ref, NbAcceptors, Transport, TransOpts, Protocol
}). init({Ref, NbAcceptors, Transport, TransOpts, Protocol}) ->
AckTimeout = proplists:get_value(ack_timeout, TransOpts, 5000),
ConnType = proplists:get_value(connection_type, TransOpts, worker),
Shutdown = proplists:get_value(shutdown, TransOpts, 5000),
ChildSpecs = [
{ranch_conns_sup, {ranch_conns_sup, start_link,
[Ref, ConnType, Shutdown, Transport, AckTimeout, Protocol]},
permanent, infinity, supervisor, [ranch_conns_sup]},
{ranch_acceptors_sup, {ranch_acceptors_sup, start_link,
[Ref, NbAcceptors, Transport, TransOpts]},
permanent, infinity, supervisor, [ranch_acceptors_sup]}
],
{ok, {{rest_for_one, 1, 5}, ChildSpecs}}.

这里-behaviour(supervisor),就是典型的supervisor类型模块

启动了ranch_conns_sup和ranch_acceptors_sup 2个进程

这是ranch的主要工作模块才慢慢显露出来,下次我们重点分析这2个模块(未完待续...)

ranch 源码分析(二)的更多相关文章

  1. ranch 源码分析(三)

    接上ranch 源码分析(二) 上次讲到了ranch_conns_sup和ranch_acceptors_sup这2个ranch的核心模块,我们接着分析 首先查看ranch_conns_sup.erl ...

  2. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  3. ranch 源码分析(完)

    接上 ranch 源码分析(三) 在上一次,根据ranch源码把大概流程理了一遍,下面我们将一些细节解释一下. ranch只是一个服务的框架,它提供了传输层协议代码(ranch_tcp 和ranch_ ...

  4. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  5. Tomcat源码分析二:先看看Tomcat的整体架构

    Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...

  6. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  7. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  8. 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>

    目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...

  9. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

随机推荐

  1. 苹果 ios 微信浏览器界面 ajax 提交带 file 的 form 总是走error方法

    1. 问题 问题出在微信端,而且是苹果机的微信端(苹果你咋这么矫情,安卓正常).:代码还是之前的代码,貌似是苹果升级系统后部分版本出现的 BUG,后来证明确实跟 ios 版本有关,网上也找过类似的解决 ...

  2. python基础(14)-反射&类的内置函数

    反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...

  3. Hive为什么要启用Metastore?

    转载来自: https://blog.csdn.net/qq_40990732/article/details/80914873 https://blog.csdn.net/tp15868352616 ...

  4. POJ 1986 Distance Queries(LCA Tarjan法)

    Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...

  5. protocol buffer简介

    一.protocol buffer简介 protocol buffer(简称PB)是google开源的一个数据序列化与反序列化工具,由于其支持多种语言.各种平台,多被用于对象的存储,远程调用等方向.用 ...

  6. 玩转spring boot——结合docker

    前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 liunx机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有 ...

  7. scanperiod 不生效

    注意:要改 target 目录下的,真正运行时加载的 logback-spring.xml

  8. BDD数据集(mask_rcnn)1

    mask_rcnn中ballon的例子 classsification VS semantic segmention VS object detection VS instance segmentio ...

  9. C语言实例:函数指针

    函数指针:函数指针数组的使用: 不带参数和返回值的函数指针: #include <stdio.h> #include <stdlib.h> //定义一个没有返回值也没有入口参数 ...

  10. jQuery安装和语法

    jQuery是一个JavaScript函数库,可实现HTML元素选取及操作.CSS 操作.HTML事件函数.JavaScript特效和动画.HTML DOM遍历和修改.AJAX等功能. 在html中引 ...