接上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. QSS独门秘籍:subcontrol

    QSS是C++ Qt中的界面美化神器,其语法和CSS区别不大,但是QSS有一个独有的功能——subcontrol,这是CSS所没有的,一个widget往往由多个子部件构成,利用subcontrol可以 ...

  2. git本地仓库 push到远程仓库出现错误

    ! [rejected] master -> master (fetch first) error: failed to push some refs to hint: Updates were ...

  3. LaTeX大于小于号

    发现大部分人只回答大于等于号.小于等于号的写法,而没有说大于.小于号的分别写法. 大于号:\textgreater 小于号: \textless 下面的后面要加空格,否则会识别错误 大于等于:\geq ...

  4. MAVEN_day03 整合SSH框架

    一.整合SSH工程环境准备 1.创建MAVEN工程>>添加>>"web.xml"文件解决工程红色叹号. new Maven Project>>在 ...

  5. 12.0-uC/OS-III任务调度

    调度器,决定了任务的运行顺序. uC/OS-III是一个可抢占的, 基于优先级的内核.根据其重要性每个任务都被分配了一个优先级.uC/OS-III支持多个任务拥有相同的优先级. 1.抢占式调度 uC/ ...

  6. docker容器与镜像

    就像cad图层概念 数据卷就是为了完成数据持久化操作

  7. PHP 二位数组按照下标排序

    1.排序得内容 array(6) { [0] => array(12) { [0] => string(3) "160" [1] => string(2) &qu ...

  8. nginx配置虚拟主机vhost的方法详解

    Nginx vhost配置,可实现基于ip.端口号.servername的虚拟主机,同时可避免直接修改主配置文件.在nginx下配置虚拟主机vhost非常方便.这篇文章主要介绍了nginx配置虚拟主机 ...

  9. [js]js设计模式小结

    js设计模式小结 工厂模式/构造函数--减少重复 - 创建对象有new - 自动创建obj,this赋值 - 无return 原型链模式 - 进一步去重 类是函数数据类型,每个函数都有prototyp ...

  10. npm 发布一个全局的指令

    我们经常使用 npm i  -g  xxxx 安装完成一个包之后,就能直接使用对应的指令.例如安装  vue-cli 或者 express 等 那么下面我们自己做一个类似的效果: 首先要对 npm 发 ...