上一篇已经分析了rpool 的三个module , 以及简单的物理关系. 这次主要分析用户进程和 worker_pool 进程还有worker_pool_worker 进程之间的调用关系. 在开始之前, 必须先明确一点, 就是一个worker_pool_worker 进程只有在处理完一个用户进程的任务之后才能开始处理另一用户进程的任务.

worker_pool 状态管理

在上一篇已经说明, worker_pool 管理了rpool 工作进程的ready idle busy 状态,从worker_pool 的代码可以看出, 对于idle 状态和busy 状态的处理逻辑是相同的.

 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};

以上是submit 请求在 available queue 不为空时的处理逻辑.

 handle_cast({run_async, Fun}, State = #state { available = [WPid | Avail1] }) ->
worker_pool_worker:submit_async(WPid, Fun),
{noreply, State #state { available = Avail1 }, hibernate};

而以上是submit_async 请求在available queue 不为空时的处理逻辑.

 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};

当某工作进程完成对用户进程任务的处理之后, cast 给worker_pool 进程 idle 消息, worker_pool 会:

1, 判断pending 是否为空, 若空, 则将工作进程add 到available中;

2, 若pending 为 next_free, 则执行submit 请求时的处理流程;

3, 若pending 为run_async, 则执行submit_async 请求时的处理流程.

submit

用户进程在调用submit 请求时的基本流程如上图所示:

1, 用户进程call 请求 worker_pool 进程 next_free

2, worker_pool 进程 获取available 中的工作进程(PidA)并返回给用户进程

3, 用户进程call 请求PidA 工作进程submit

工作进程PidA 在ready 或 idle 时,工作进程的state 信息就会被置为undefined .

也就是在first message 到达工作进程时, 工作进程的state 信息为undefined, 那么工作进程处理上图first message 的逻辑为:

 handle_cast({next_job_from, CPid}, undefined) ->
MRef = erlang:monitor(process, CPid),
{noreply, {from, CPid, MRef}, hibernate};

也就是 monitor 用户进程UPA, 并将自身的state 重置为 {from, CPid, MRef}, 然后等待UPA 进程的submit 请求, 也就是second message .

如果在这中间, UPA 异常退出, 工作进程就会收到{'DOWN' ... } message:

 handle_info({'DOWN', MRef, process, CPid, _Reason}, {from, CPid, MRef}) ->
ok = worker_pool:idle(self()),
{noreply, undefined, hibernate};

然后将state 重置为undefined .

submit_async

用户进程在调用submit_async 请求时的基本流程如上图所示:

1, 用户进程cast 请求worker_pool 进程 run_async 参数是需要execute Fun

2, worker_pool 进程获取available 中的工作进程(PidA)并 cast submit_async 请求给PidA 参数为PidA 和 Fun

3, 然后进程在handle_cast callback 中进行处理.

 handle_cast({submit_async, Fun}, undefined) ->
run(Fun),
ok = worker_pool:idle(self()),
{noreply, undefined, hibernate};

和submit 操作相比, 工作进程在处理submit_async 请求时,不需要monitor 用户进程(UPA), 不需要将Fun execute 执行的结果返回用户进程.

总结

在Mac 下omnigraffle 真的挺好用的,就是太贵了. :(

Erlang pool management -- RabbitMQ worker_pool 2的更多相关文章

  1. Erlang pool management -- RabbitMQ worker_pool

    在RabbitMQ中,pool 是以worker_pool 的形式存在的, 其主要用途之一是对Mnesia transaction 的操作. 而在RabbitMQ 中, pool 中的worker 数 ...

  2. Erlang pool management -- Emysql pool optimize

    在上一篇关于Emysql pool (http://www.cnblogs.com/--00/p/4281938.html)的分析的最后提到 现在的emysql_conn_mgr gen_server ...

  3. Erlang pool management -- Emysql pool

    从这篇开始,这一系列主要分析在开源社区中,Erlang 相关pool 的管理和使用. 在开源社区,Emysql 是Erlang 较为受欢迎的一个MySQL 驱动. Emysql 对pool 的管理和使 ...

  4. Ubuntu16.04下,erlang安装和rabbitmq安装步骤

    文章来源: Ubuntu16.04下,erlang安装和rabbitmq安装步骤 准备工作,先下载erlang和rabbitmq的安装包,注意他们的版本,版本不对可能会导致rabbitmq无法启动,这 ...

  5. 使用kombu的producer pool 向rabbitmq瞬间发送大量消息

    kombu比pika感觉考虑得全面多了,不知道为什么用的人好像少? 生产端是 python-socket.io 的client   接受socketio 消息后, 发到rabbitmq 按时序进行处理 ...

  6. erlang pool模块。

    出自: http://blog.sina.com.cn/s/blog_96b8a154010168ti.html

  7. Erlang及Rabbitmq安装

    1. 下载erlang源代码及RabbitMQ rpm安装包      $ wget http://www.erlang.org/download/otp_src_R16B02.tar.gz $ wg ...

  8. linux centos7 erlang rabbitmq安装

    最终的安装目录为/opt/erlang 和 /opt/rabbitmq wget http://erlang.org/download/otp_src_21.0.tar.gztar zxvf otp_ ...

  9. centos6.5 以 zero-dependency Erlang from RabbitMQ 搭建环境

    rabbitmq 官方安装文档可参考:http://www.rabbitmq.com/install-rpm.html  ,由于rabbitmq 使用Erlang 开发的,运行环境需要用到Erlang ...

随机推荐

  1. JSP DAO(Model)

    示例代码: 1. Users类 package com.po; public class Users { private String username; private String passwor ...

  2. Java Comparator方法 和 Comparable接口

    默认的排序方法: 让类继承Comparable接口,重写compareTo方法. 示例代码: package com.imooc.collection; import java.util.HashSe ...

  3. mongodb 中 Aggregation 的管道和分片集合( Pipeline and Sharded Collections)

    mongodb 中的aggretion 中,如果管道中存在一个与之相匹配的shard key ,那么这个管道只运行在与之相匹配的shard 中,在以前(3.2),pipeline 被分流,最后又由pr ...

  4. Python面向对象编程高级特性

    ***这里还是根据网上资料,主要是廖雪峰老师的教程学习的笔记,主要介绍python面向对象的高级特性,笔记不全,只是记录自己觉得容易出错的地方*** 1.python作为一种动态语言,他的动态绑定机制 ...

  5. 80X86寄存器详解<转载>

    引子 打算写几篇稍近底层或者说是基础的博文,浅要介绍或者说是回顾一些基础知识, 自然,还是得从最基础的开始,那就从汇编语言开刀吧, 从汇编语言开刀的话,我们必须还先要了解一些其他东西, 像  CPU ...

  6. Spring的DI初步

    DI:依赖注入 第一个DEMO:域属性注入 java类:(Car类和Stu类,学生有一辆小汽车) package cn.dawn.day02di; /** * Created by Dawn on 2 ...

  7. network namespace连接的4种方法及性能

    veth pair # add the namespaces ip netns add ns1 ip netns add ns2 # create the veth pair ip link add ...

  8. 读写properties文件方法

    按key读取properties文件中的value public static String readSystemConfig(String key){ Properties prop = new P ...

  9. mysql: instr 多个字段 like数据

    你是否一直在寻找比MySQL的LIKE语句更高效的方法的,下面我就为你介绍几种. SELECT * FROM `order_shop` where instr(uuid,  'b') > 0 g ...

  10. 转:autofac在mvc和webapi集成的做法

    本文转自:http://www.cnblogs.com/Hai--D/p/5992573.html var builder = new ContainerBuilder(); // Mvc Regis ...