rabbitmq之work_pool
worker_pool_worker的作用是用来完成数据操作。
如何获取worker是从worker_pool里获取,并由worker_pool管理。
起动时间:
-rabbit_boot_step({worker_pool,
[{description, "worker pool"},
{mfa, {rabbit_sup, start_supervisor_child,
[worker_pool_sup]}},
{requires, pre_boot},
{enables, external_infrastructure}]}).
在起动顺序中,work_pool是由pre_boot之后,external_infrastructure之后起动的。起动一个worker_pool进程,并起动Wcount个work_pool_worker进程,Wcount是由erlang:system_info(schedulers)决定的。
init([WCount])
->
{ok,
{{one_for_one, 10, 10},
[{worker_pool,
{worker_pool, start_link, []}, transient,
16#ffffffff,
worker, [worker_pool]} |
[{N,
{worker_pool_worker, start_link, []}, transient, 16#ffffffff,
worker,
[worker_pool_worker]} || N <- lists:seq(1, Wcount)]]}}.
worker_pool_worker起动的时候会将通过worke_pool:read(self())来监控起来,并将此进程放置于state中avaliable列表中。当worker_pool_worker
down掉时,worker_pool则会将此进程从avaliable队表中删除掉。
init([])
->
ok
= file_handle_cache:register_callback(?MODULE,
set_maximum_since_use,
[self()]),
ok
= worker_pool:ready(self()),
put(worker_pool_worker,
true),
{ok,
undefined, hibernate,
{backoff,
?HIBERNATE_AFTER_MIN, ?HIBERNATE_AFTER_MIN, ?DESIRED_HIBERNATE}}.
worker_pool.erl
ready(WPid)
-> gen_server2:cast(?SERVER, {ready, Wpid}).
handle_cast({ready,
WPid}, State) ->
erlang:monitor(process,
WPid),
handle_cast({idle,
WPid}, State);
handle_cast({idle,
WPid}, State = #state { available = Avail,
pending
= Pending }) ->
{noreply,
case
queue:out(Pending) of
{empty,
_Pending} ->
State
#state { available = ordsets:add_element(WPid, Avail) };
{{value,
{next_free, From, CPid}}, Pending1} ->
worker_pool_worker:next_job_from(WPid,
CPid),
gen_server2:reply(From,
WPid),
State
#state { pending = Pending1 };
{{value,
{run_async, Fun}}, Pending1} ->
worker_pool_worker:submit_async(WPid,
Fun),
State
#state { pending = Pending1 }
end,
hibernate};
handle_info({'DOWN',
_MRef, process, WPid, _Reason},
State
= #state { available = Avail }) ->
{noreply,
State #state { available = ordsets:del_element(WPid, Avail) },
hibernate};
如果有submit动作,获取空闲的worker,并作
submit(Fun,
ProcessModel) ->
case
get(worker_pool_worker) of
true
-> worker_pool_worker:run(Fun);
_
-> Pid = gen_server2:call(?SERVER, {next_free, self()},
infinity),
worker_pool_worker:submit(Pid,
Fun, ProcessModel)
end.
此时应获取一个空闲的worker_pool_worker,并让此worker装备一下,返回worker
Pid。
handle_call({next_free,
CPid}, _From, State = #state { available =
[WPid
| Avail1] }) ->
worker_pool_worker:next_job_from(WPid,
CPid),
{reply,
WPid, State #state { available = Avail1 }, hibernate};
worker_pool_worker准备工作
next_job_from(Pid,
CPid) ->
gen_server2:cast(Pid,
{next_job_from, Cpid}).
work_pool_worke刚起来的时候state是undefined,当需要自己去完成工作的时候,worker会将work_pool进程监控起来,以便pool在使用自己执行操作的时候且pool异常时能够释放自己。
handle_cast({next_job_from,
CPid}, undefined) ->
MRef
= erlang:monitor(process, CPid),
{noreply,
{from, CPid, MRef}, hibernate};
submit(Pid,
Fun, ProcessModel) ->
gen_server2:call(Pid,
{submit, Fun, self(), ProcessModel}, infinity).
将pool解监控,返回pool执行结果,释放自己,state重回undefined。
handle_call({submit,
Fun, CPid, ProcessModel}, From, {from, CPid, MRef}) ->
erlang:demonitor(MRef),
gen_server2:reply(From,
run(Fun, ProcessModel)),
ok
= worker_pool:idle(self()),
{noreply,
undefined, hibernate};
参考文献:
Erlang:RabbitMQ源码分析 5. worker pool 实现分析. http://m.blog.csdn.net/blog/liaosongbo/39317829
rabbitmq之work_pool的更多相关文章
- Erlang pool management -- RabbitMQ worker_pool
在RabbitMQ中,pool 是以worker_pool 的形式存在的, 其主要用途之一是对Mnesia transaction 的操作. 而在RabbitMQ 中, pool 中的worker 数 ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- RabbitMq应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- 如何优雅的使用RabbitMQ
RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...
- RabbitMq应用一的补充(RabbitMQ的应用场景)
直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...
- RabbitMq应用一
RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- windows下 安装 rabbitMQ 及操作常用命令
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...
随机推荐
- iOS 初学UITableView、UITableViewCell、Xib
注意事项: 1.一个.xib里面最多设置一个cell 2.要仔细调整自动布局,其实它不太好用 3.记得设置<UITableViewDataSource>委托 4.记得在ViewContro ...
- iOS学习14之OC NSNumber + NSValue
1.NSNumber 数值类. 作用:实现基本数据类型与OC对象类型的相互转化. 1> NSNumber创建对象 // 初始化方法 NSNumber *num1 = [[NSNumber all ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- Mongoose学习参考文档——基础篇
Mongoose学习参考文档 前言:本学习参考文档仅供参考,如有问题,师请雅正 一.快速通道 1.1 名词解释 Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model ...
- 读书笔记:javascript高级技巧(二)
四.惰性载入函数 因为浏览器兼容的原因,我们的javascript代码会有大量的if语句,将执行引导到正确的代码中,看如下函数: function createXHR(){ if (typeof XM ...
- 【Oracle】如何导库
正常倒库: 步骤一:在需要导入的库里建立一个新的数据库用户 create user sms533 identified by sms533; grant dba,create session to s ...
- Linux之进程管理
==================================================================================================== ...
- [iOS-UI]给输入框添加清除按钮的代码
UIButton *clearButton = [self.textField valueForKey:@"_clearButton"]; [clearButton setImag ...
- as3如何做出残影效果
在页游中,时不时能看到人物做一些快速移动动作如冲刺时,有残影效果,强化了画面表现.实际人肉眼之所以能看到残影的效果,是因为观察到的物体会在人视线中残留几十毫秒时间,当运动物体运动太快时,人肉眼所见未能 ...
- CentOS7 网络管理相关命令
contos7 网卡配置文件自动识别ifcfg开头的文件(包括目录) CentOS7网卡命名规则: CentOS 7 开始对于网卡的编号则有另一套规则, 网卡的界面代号现在与网卡的来源有关,基本上的网 ...