上次提到的一个挑战,公开出来的一些代码,这两天抽时间仔细读了一下,感觉对OTP了解更多了(以前没怎么接触过完整的应用),下面是一些阅读笔记和简单的分析
hotwheels
程序入口 hotwheels,启动app hotwheels,通过hotwheels.app查看入口模块,
app的入口模块hotwheels_app,作为一个application,定义了几个子进程:
* 模块hotwheels_acceptor,作为TCP Server,监听端口,接受请求,名字为hotwheels_sup
* 模块topic,作为topic管理器,hotwheels_topic_sup
* 启动自己作为一个supervisor,名字为hotwheels_transport_sup
** 定义了一个child,是transport
TCP Server
TCP Server是一个gen_server,处理掉了几乎所有的异常情况,包括打开连接过多(Too Many Open Files),这时候他会sleep一会儿,然后继续处理
TCP Server启动的时候开始监听端口,接受请求,当有请求进来的时候,就让Child Instance Supervisor(hotwheels_app)启动一个
Child(transport)来处理这个客户端,这段代码是:
handle_connection(State, Socket) ->
{ok, Pid} = hotwheels_app:start_transport(State#state.port),
ok = gen_tcp:controlling_process(Socket, Pid),
%% Instruct the new handler to own the socket.
(State#state.module):set_socket(Pid, Socket).
transport
transport负责处理客户端连接,为了更灵活的处理,socket都被设置成{active,once}(这个原理请见xxx的分析)。
transport也是一个gen_server,在启动的时候没有注册名字,因此可以启动n个实例(由application来启动)
因为socket是active once的,因此所有收到的数据都将以message的方式送来,都需要通过handle_info来处理,客户端会发三种消息来,
SUBSCRIBE,UNSUBSCRIBE,PUBLISH,处理这三种消息的时候都是先将socket重新设置成{active,once},然后将消息交给topic去处理
transport设置了trap_exit为true,抓住并忽略掉了处理进程(topic)失败的情况
如果收到ACK消息,则应答一个ACK消息,同时带上时间戳
如果收到不认识的binary数据,则直接将数据发送给客户端(为啥?)
topic
topic 负责是pub sub的入口,负责调度,如果要sub的topic不存则,则通知pubsub模块初始化一个新的,然后用mapper模块记录下来
真正的pub,sub操作是由pubsub模块完成的,每个topic都由一个单独的pubsub进程管理
mapper
mapper模块很简单,就是管理进程的Pid和Topic名字之间的隐射关系,同时维护双向的关系,pid2topic,topic2pid,建立两张ets表,
分别保存这两种隐射关系
pubsub
记录每个subscribors,记录的数据结构是{Pid,Ref,Sock},Pid是subscribor的pid,Ref是sub的时候monitor的reference,Sock
是该客户端连接的socket,消息进来(publish)的时候:
handle_cast({publish, Msg}, State) ->
io:format("info: ~p~n", [ets:info(State#state.subs)]),
{A, B, C} = Start = now(),
Msg1 = <<A:32, B:32, C:32, ?MESSAGE, Msg/binary>>,
F = fun({_, _, Sock}, _) -> erlang:port_command(Sock, Msg1) end, %% 使用port_command来发送
erlang:process_flag(priority, high),
ets:foldl(F, ok, State#state.subs), %% 遍历ets里的所有内容
End = now(),
erlang:process_flag(priority, normal),
io:format("time: ~p~n", [timer:now_diff(End, Start) / 1000]),
{noreply, State};
分享到:
- 2009-08-31 11:56
- 浏览 2515
- 评论(1)
- 论坛回复 / 浏览 (1 / 2048)
- 查看更多
相关推荐
单人+电脑对手,难度各异,使用OpenGL和IrrLicht图形引擎进行简单的飙车游戏,从各种汽车中选择,每种汽车都有自己的视觉设置并在高速公路上比赛,每个晚上只有20秒! !
风火轮风火轮的后端用户模型ID 创建于更新于电子邮件密码角色(客户|所有者|交付)用户CRUD 创建帐号登录查看个人资料编辑个人资料验证邮件餐厅模型名称类别地址封面图片编辑餐厅删除餐厅查看分类查看餐厅类别(分页...
Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility
FOX Wheels Car Affordability
Windows下适用于python 3.5的编译好的Wheels,包括32位和64位。
German Language - THERMOPLASTIC GEAR WHEELS - CYLINDRICALGEARS - CALCULATION 行业标准
wheels-in-tagil
<LabVIEW入门与实战开发100例>--->22Ch Train Wheels Monitor
python库,解压后可用。 资源全名:psutil_wheels-5.8.0-cp310-cp310-win_amd64.whl
Force feedback support for Logitech Gaming Wheels.
“Wheels vs. tracks” – A fundamental evaluation from the traction perspective
经典的时间轮算法论文,时间轮的思想应用范围非常广泛,各种操作系统的定时任务调度,Crontab,还有基于java的通信框架Netty中也有时间轮的实现,几乎所有的时间任务调度系统采用的都是时间轮的思想。...
英语Wheels北师大必修PPT课件.pptx
Food-Wheels-Mobile-源码.rar
一个基于Arduino和基于蓝牙的Hot Wheels终点线计时器,用于记录汽车的速度并确定每种热量的获胜者。
资源分类:Python库 所属语言:Python 资源全名:build_install_wheels-0.2.0.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
Groovy Recipes Greasing the Wheels of Java.pdf
ESP idf-python-wheels IDF工具要求的Windows Python Wheel的构建。 构建包含分支所需的所有轮子: 版本/v4.2 版本/v4.1.1 掌握 用法 .\Build-Wheels.ps1 -Branch "master" -CompileWheels @("greenlet", ...