emqttd 不是内部或外部命令_emqttd随笔
esockd_connection_sup不是一个严格的supervisor。它只是一个gen_server。这是因为他的特殊性决定的。
start_link(Options, MFArgs, Logger) ->
gen_server:start_link(?MODULE, [Options, MFArgs, Logger], []).
supervisor中的必须有重启策略,如果没有在spec中填写默认就是one_for_one。这几种重启策略都会重启子进程。
但是对于sockt连接,断了就是断了,不应该重启的。因此不需要什么重启策略。那么supervisor怎么也得有个监督关系啊,
需要的是当子进程挂了的时候,supervisor要收到消息。
那他是怎么启动子进程(socket连接)的呢?
在esockd_connection_sup.erl中,Conn:start_link(MFArgs)函数调用 emqttd_client:start_link/2 来创建client进程。
esockd_connection_sup.erl:
start_connection(Sup, Mod, Sock, SockFun) ->
case call(Sup, {start_connection, Sock, SockFun}) of
{ok, Pid, Conn} ->
% transfer controlling from acceptor to connection
Mod:controlling_process(Sock, Pid),
Conn:go(Pid),
{ok, Pid};
{error, Error} ->
{error, Error}
end.
handle_call({start_connection, Sock, SockFun}, _From,
State = #state{conn_opts = ConnOpts, mfargs = MFArgs,
curr_clients = Count, access_rules = Rules}) ->
case inet:peername(Sock) of
{ok, {Addr, _Port}} ->
case allowed(Addr, Rules) of
true ->
Conn = esockd_connection:new(Sock, SockFun, ConnOpts),
case catch Conn:start_link(MFArgs) of
{ok, Pid} when is_pid(Pid) ->
...
emqttd_client:start_link/2 调用 proc_lib:spawn_link/3 来启动进程:
emqttd_client.erl:
start_link(Conn, Env) ->
{ok, proc_lib:spawn_link(?MODULE, init, [[Conn, Env]])}.
为什么这里要使用proc_link:spwan_link/3来启动连接进程呢?因为这个函数最终是调用erlang:spawn_link来启动,并自动创建link。
该函数和erlang:start_link的方式区别是spawn_link属于异步启动进程。一调用就会返回子进程ID。
他的用处在emqttd_client:init中看到:
init([Conn0, Env]) ->
{ok, Conn} = Conn0:wait(),
case Conn:peername() of
{ok, Peername} -> do_init(Conn, Env, Peername);
{error, enotconn} -> Conn:fast_close(),
exit(normal);
{error, Reason} -> Conn:fast_close(),
exit({shutdown, Reason})
end.
这里的 Conn0:wait():
esockd_connection.erl:
wait(Conn = ?CONN_MOD) ->
receive {go, Conn} -> upgrade(Conn) end.
使用 receive 来接受消息{go, Conn}。如果emqttd_client:start_link中不使用spawn_link来启动进程,那么在 init 中就会卡死。
这样在 esockd_connection_sup:start_connection(Sup, Mod, Sock, SockFun) 中,Conn:go()就不会被执行。因此出现wait()一直
等待go()发出消息。
如果使用spawn_link就会直接返回,init中执行wait,go被执行后发出消息由wait收到,然后才执行do_init(Conn, Env, Peername)
函数。
另外,esockd_connection_sup 中和子进程link之后,相互都会收到对方 exit 的消息,这样可能 esockd_connection_sup 可能会因为
子进程挂掉而挂掉,为了避免这种情况,esockd_connection_sup 启动的时候在init中设置 process_flag(trap_exit, true), 这样
可以将子进程发送的 exit 消息转化为消息{'EXIT', Pid, Reason},从而避免 esockd_connection_sup 被牵连而挂掉。
handle_info({'EXIT', Pid, Reason}, State = #state{curr_clients = Count, logger = Logger}) ->
...
总结一下:只要理解了spawn_link的异步方式就可以理解wait和go了。
emqttd 不是内部或外部命令_emqttd随笔相关推荐
- jdk12‘javac‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
前言: 安装JDK12遇到的问题以及学习过程, 我第一次用网上的安装办法,下载EXE后,配置好三个环境变量后运行,不行. 解决过程: 问题1:安装后javac命令运行时报错 jdk12'javac' ...
- vue 不是内部或外部命令,也不是可运行的程序 或批处理文件
vue 安装 vue-cli 成功之后 控制台查看vue的版本 提示 vue 不是内部或外部命令,也不是可运行的程序 或批处理文件 我的问题 就环境变量没有配置 下面以window 10 系统说下我的 ...
- 安装需要的第三方库时,命令行输入pip提示不是内部或外部命令
简介 在做Python开发时,安装需要的第三方库时,大多数人喜欢选择在命令行用pip进行安装. 然而有时敲入pip命令会提示'pip'不是内部或外部命令..如图: 解决办法 1.在python安装目录 ...
- ‘vue-cli-service‘ 不是内部或外部命令,也不是可运行的程序
从github上面下载了一个项目,在本地执行 但是一直出现这样的错误 vue-cli-service 不是内部命令 > vue-cli-service serve'vue-cli-service ...
- wsimport 不是内部或外部命令,也不是可运行的程序或批处理文件
我的是windows10系统,在生成webservice代码的时候提示这个错误: wsimport 不是内部或外部命令,也不是可运行的程序或批处理文件 看到网上各种帖子,各位大神都是认为Jdk的环境部 ...
- 不是内部或外部命令 windows10 执行 linux命令
不是内部或外部命令 windows10 执行 linux命令 打开 PowerShell 输入linux命令
- “adb不是内部或外部命令,也不是可执行的应用程序”错误原因及解决方法
用SQLite时,可能会出现这样的错误. 原因可能是环境变量PATH没有配置或配置不正确.应该把adb.exe 所在目录加入到PATH环境变量.例如:C:\Program Files\android- ...
- win10配置java环境变量,解决javac不是内部或外部命令等问题
win10配置java环境变量,解决javac不是内部或外部命令等问题 * 1,首先进入环境变量页面 2,在系统变量下面配置 JAVA_HOME:你自己的jdk的路径 CLASSPATH= .;%J ...
- android的dmtracedump工具生成trace文件图片 'dot' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
http://jingyan.baidu.com/article/c910274bfa6c1fcd361d2df7.html http://www.cnblogs.com/albert1017/p/3 ...
最新文章
- 刻意练习:LeetCode实战 -- 不同的二叉搜索树
- %config InlineBackend.figure_format=svg#矢量图设置
- 从CIO视角出发审视云环境下的安全议题
- 分不清的InputStream和OutputStream
- 计算机应用基础期末考试电大,(电大)期末考试2017年广播电视大学网考《计算机应用基础》重点复习题目汇总版(理论题及操作题)...
- 利用php-console和Chrome开发者工具实现PHP应用的printf
- php 递归栏目名叠加,thinkPHP实现递归循环栏目并按照树形结构无限极输出的方法,thinkphp递归...
- 区块链未来发展三大关键词,华为云如何见招拆招?
- 1.5_insert_sort_插入排序
- 跟随我在oracle学习php(42)
- 精通JavaScript+jQuery:100%动态网页设计密码 中文PDF扫描版
- GO 语言的GOROOT 和GOPATH
- [渝粤教育] 四川大学 土木工程概论 参考 资料
- Java软件工程师面试常见问题集锦之一
- 数控技能大赛计算机程序设计员,第八届全国数控技能大赛决赛获奖名单
- Win11笔记本耗电大怎么解决?Win11耗电快怎么办?
- 获取当前日期的上一个月和后三个月。
- 中山大学计算机学院交换生去国外,中山大学取消与伯克利大学交换生项目
- 【论文笔记】Bullseye Polytope: A Scalable Clean-Label Poisoning Attack with Improved Transferability
- SpringCloudAlibaba看的某马视频笔记