jjmrocha / worker_pool

Erlang worker pool

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DEPRECATED

Use async_pool from jjmrocha/async instead

===============

worker_pool

Erlang abstract worker pool

Worker_pool is a simple permanent pool of erlang processes heavily inspired on bfrog/hottub implementation.

Installation

Using rebar:

{deps, [
	{worker_pool, ".*", {git, "https://github.com/jjmrocha/worker_pool.git", "master"}}
]}.

Starting and stopping pools

The module worker_pool_sup provides 2 functions to create a worker pool (start_pool/2 and start_pool/3) and a function to drop the pool stop_pool/1.

%% Starts a pool with a process for each core.
worker_pool_sup:start_pool(PoolName, StartFunction) -> supervisor:startlink_ret() when
  PoolName :: atom(),
  StartFunction :: {Module, Function, Args},
  Module :: atom(),
  Function :: atom(),
  Args :: list().
  
worker_pool_sup:start_pool(PoolName, WorkerCount, StartFunction) -> supervisor:startlink_ret() when
  PoolName :: atom(),
  WorkerCount :: integer(),
  StartFunction :: {Module, Function, Args},
  Module :: atom(),
  Function :: atom(),
  Args :: list().
  
worker_pool_sup:stop_pool(PoolName :: atom()) -> ok.    

Worker instances

The module worker_pool provides the following functions to interact with the worker instances.

worker_pool:cast(PoolName :: atom(), Msg :: term()) -> ok.

worker_pool:call(PoolName :: atom(), Msg :: term()) -> term().

worker_pool:call(PoolName :: atom(), Msg :: term(), Timeout :: integer()) -> term().

worker_pool:multicast(PoolName :: atom(), Msg :: term()) -> ok.   

Additionally all messages received by the worker_pool process will be forwarded to one of the worker pool processes.

Using worker_pool

Worker implementation

Create a module with your worker's logic, the following example uses an gen_server but can be any type of process, the only condition is that the start function must return {ok, Pid :: pid()}.

-module(math).

-behaviour(gen_server).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([start_link/0]).
-export([add/2, print/1]).

%% Starts a worker process, each worker process will be a gen_server
start_link() ->
    gen_server:start_link(?MODULE, [], []).

%% Sends a call request to one off the worker processes
add(A, B) ->
    worker_pool:call(?MODULE, {add, A, B}).

%% Sends a cast message for all worker processes
print(Msg) ->
    worker_pool:multicast(?MODULE, Msg).

init([]) ->
    {ok, none}.

handle_call({add, A, B}, _From, State) ->
    Reply = A + B,
    {reply, Reply, State}.

handle_cast(Msg, State) ->
    io:format("~p: ~p~n", [self(), Msg]),
    {noreply, State}.

handle_info(Info, State) ->
    error_logger:error_msg("~p(~p): Unexpected message ~p\n", [?MODULE, self(), Info]),
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

Start pool

Starting a pool will start the following processes:

  • 1 worker_pool_sup process - Registered as "<pool_name>_sup", i.e. in this case the worker poll name is "math", so the supervisor name will "math_sup"
  • 1 worker_pool process (under worker_pool_sup) - Registered as "<pool_name>", i.e. in this case the name will be "math"
  • 1 worker_sup process (under worker_pool_sup)
  • n worker processes (under worker_sup)
1> worker_pool_sup:start_pool(math, {math, start_link, []}).

=INFO REPORT==== 26-Sep-2015::23:53:15 ===
math starting on [<0.36.0>]...
{ok,<0.35.0>}

Using the pool

2> math:add(3, 4).
7
3> math:print("I love Erlang").
<0.40.0>: "I love Erlang"
<0.39.0>: "I love Erlang"
<0.38.0>: "I love Erlang"
<0.41.0>: "I love Erlang"
ok

Stopping the pool

4> worker_pool_sup:stop_pool(math).
ok

About

Erlang worker pool

License:Apache License 2.0


Languages

Language:Erlang 100.0%