eFaw 是一个轻量级的 Erlang worker 编排库,围绕三种运行模式展开:
- worker 模式:固定命名 worker,直接分发任务 适用于任务处理时间比较短的任务
- factory 模式:任务队列加弹性 worker,适用于可能单个任务处理时间不确定的场景 别的任务不会因为一个任务耗时太长而导致别的任务跟着等待
- pool 模式:借出并归还 worker 进程,适合一次操作中独占某个 worker 的场景 比如说数据驱动 主要是为了支持一下原生的一些数据库驱动库的写法
项目依赖 eGbh 和 eLfq,其中 eLfq 作为 factory 与 pool 模式底层的无锁队列实现。
rebar3 compile
eFaw:start().
eFaw:stop().
src/Faw/fwWTP.erl 是默认的 worker 实现。如果你通过 wMod 指定自定义 worker 模块,需要兼容以下回调形式:
- start_link/3:用于 factory 和 pool worker
- start_link/4:用于固定命名 worker
- work/1:执行具体任务
通用配置定义在 include/eFaw.hrl:
- wMod:worker 模块,默认值是 fwWTP
- wFCnt:固定 worker 数量,默认值是 30
- wTCnt:临时 worker 数量上限,默认值是 20
- wKeepTime:空闲保留时间,单位毫秒,默认值是 3600000
- fTLfl:factory 任务负载阈值,默认值是 10000
- fTMax:允许接收的最大任务队列长度,默认值是 infinity
- wArgs:worker 初始化参数
Worker 模式会创建一组固定命名的 worker,并直接把任务分发给这些 worker。
eFaw:openW(my_worker_group, [
{wMod, fwWTP},
{wFCnt, 8},
{wArgs, undefined}
]).
eFaw:doWork(my_worker_group, task1).
eFaw:doSyncWork(my_worker_group, task2).
eFaw:closeW(my_worker_group).
主要接口:
- start/0
- stop/0
- openW/2
- closeW/1
- getWork/1
- getWork/2
- doWork/2
- doWork/3
- doSyncWork/2
- doSyncWork/3
- doSyncWork/4
Factory 模式会维护一个任务队列。空闲 worker 会优先直接消费任务,当负载超过设定阈值时,manager 可以按配置补充临时 worker。
eFaw:openF(my_factory, [
{wMod, fwWTP},
{wFCnt, 4},
{wTCnt, 8},
{fTLfl, 100},
{fTMax, 10000}
]).
eFaw:inWork(my_factory, task1).
eFaw:inWorks(my_factory, [task1, task2, task3]).
eFaw:inSyncWork(my_factory, task2).
eFaw:sizeF(my_factory).
eFaw:closeF(my_factory).
主要接口:
- openF/2
- closeF/1
- sizeF/1
- hireW/3
- inWork/2
- inWorks/2
- inSyncWork/2
- inSyncWork/3
Pool 模式适合这样的场景:调用方需要借出一个 worker 进程,围绕这个 worker 执行一段逻辑,完成后再把它归还。
eFaw:openPool(my_pool, [
{wMod, fwWTP},
{wFCnt, 16},
{wKeepTime, 60000},
{wArgs, undefined}
]).
手动借出和归还:
Pid = eFaw:checkout(my_pool),
Ret = my_worker_api:do_something(Pid),
eFaw:checkIn(my_pool, Pid).
或者使用 transaction/2 保证自动归还:
eFaw:transaction(my_pool, {fun(Pid) ->
my_worker_api:do_something(Pid)
end, []}).
eFaw:transaction(my_pool, {my_worker_api, do_something, [Arg1, Arg2]}).
主要接口:
- openPool/2
- closePool/1
- hireP/2
- checkout/1
- checkIn/2
- alivePWorker/1
- transaction/2
- checkOut/1 成功时直接返回 worker 的 pid;如果进程池不存在或已满,则返回错误元组。
- checkIn/2 正常情况下应当使用进程池名称和 worker pid 进行归还。
- transaction/2 是更安全的 pool 接口,因为即使回调抛错,它也能保证 worker 被归还。
- wKeepTime 用来控制 pool worker 最长允许空闲多久,超过后会被 pool manager 清理。
最小可运行的 worker 示例可以参考 src/Faw/fwWTP.erl。