Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
yosukehara committed Jan 20, 2017
2 parents 986422b + 7c7f929 commit 126b320
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 44 deletions.
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
language: erlang
script: "make"
notifications:
email: false
otp_release:
- R16B03-1
- 17.5
- 18.3
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# leo_pod - A Fast Erlang worker pool manager

**leo_pod** is an Erlang worker pool manager.
It is implemented no to use ETS (Erlang Term Storage).
This is because we met a problem of ETS when we run it on high spec machines.
[![Build Status](https://travis-ci.org/leo-project/leo_pod.svg?branch=develop)](https://travis-ci.org/leo-project/leo_pod)

**leo_pod** is an Erlang worker pool manager, which does not use ETS(Eralng Term Storage).

## Usage

Expand Down
4 changes: 2 additions & 2 deletions src/leo_pod.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
%%
%% Leo POD
%%
%% Copyright (c) 2012-2016 Rakuten, Inc.
%% Copyright (c) 2012-2017 Rakuten, Inc.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
Expand All @@ -23,7 +23,7 @@
{application, leo_pod,
[
{description, "leo_pod manages worker process pools"},
{vsn, "0.6.7"},
{vsn, "0.6.8"},
{applications, [
kernel,
stdlib
Expand Down
2 changes: 1 addition & 1 deletion src/leo_pod.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%%
%% Leo POD
%%
%% Copyright (c) 2012-2015 Rakuten, Inc.
%% Copyright (c) 2012-2017 Rakuten, Inc.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
Expand Down
30 changes: 21 additions & 9 deletions src/leo_pod_manager.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%%
%% Leo POD
%%
%% Copyright (c) 2012-2015 Rakuten, Inc.
%% Copyright (c) 2012-2017 Rakuten, Inc.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
Expand Down Expand Up @@ -61,6 +61,15 @@
}).


-define(new_num_overflow(_CurNumOverflow),
case _CurNumOverflow < 1 of
true ->
0;
false ->
_CurNumOverflow - 1
end).


%% ===================================================================
%% API functions
%% ===================================================================
Expand Down Expand Up @@ -165,7 +174,7 @@ init([NumOfChildren, MaxOverflow, WorkerMod, WorkerArgs, InitFun]) ->
{ok, Children} ->
{ok, #state{num_of_children = NumOfChildren,
max_overflow = MaxOverflow,
num_overflow = MaxOverflow,
num_overflow = 0,
worker_mod = WorkerMod,
worker_args = WorkerArgs,
worker_pids = Children}};
Expand All @@ -179,7 +188,8 @@ handle_call(stop,_From,State) ->
{stop, normal, ok, State};

handle_call(checkout, _From, #state{worker_pids = [],
num_overflow = 0} = State) ->
max_overflow = MaxOverflow,
num_overflow = NumOverflow} = State) when MaxOverflow =< NumOverflow ->
{reply, {error, empty}, State};

handle_call(checkout, _From, #state{worker_mod = WorkerMod,
Expand All @@ -190,7 +200,7 @@ handle_call(checkout, _From, #state{worker_mod = WorkerMod,
case start_child(WorkerMod, WorkerArgs) of
{ok, ChildPid} ->
{{ok, ChildPid},
State#state{num_overflow = NumOverflow - 1}};
State#state{num_overflow = NumOverflow + 1}};
{error, _Cause} ->
{{error, empty}, State}
end,
Expand All @@ -205,7 +215,9 @@ handle_call({checkin, WorkerPid}, _From, #state{num_of_children = NumOfChildren,
worker_pids = Children} = State) ->
case length(Children) >= NumOfChildren of
true ->
{reply, ok, State#state{num_overflow = NumOverflow + 1}};
%% ?debugVal(WorkerPid),
true = erlang:exit(WorkerPid, kill),
{reply, ok, State#state{num_overflow = ?new_num_overflow(NumOverflow)}};
false ->
NewChildren = [WorkerPid|Children],
{reply, ok, State#state{worker_pids = NewChildren}}
Expand All @@ -217,8 +229,7 @@ handle_call(status, _From, #state{num_of_children = NumOfChildren,
worker_pids = Children} = State) ->
case length(Children) of
0 ->
{reply, {ok, {NumOfChildren + MaxOverflow - NumOverflow,
0, NumOverflow}}, State};
{reply, {ok, {NumOfChildren + NumOverflow, 0, NumOverflow}}, State};
N ->
{reply, {ok, {NumOfChildren - N, N, MaxOverflow}}, State}
end;
Expand All @@ -240,7 +251,9 @@ handle_cast({checkin_async, WorkerPid}, #state{num_of_children = NumOfChildren,
worker_pids = Children} = State) ->
case length(Children) >= NumOfChildren of
true ->
{noreply, State#state{num_overflow = NumOverflow + 1}};
%% ?debugVal(WorkerPid),
true = erlang:exit(WorkerPid, kill),
{noreply, State#state{num_overflow = ?new_num_overflow(NumOverflow)}};
false ->
NewChildren = [WorkerPid|Children],
{noreply, State#state{worker_pids = NewChildren}}
Expand Down Expand Up @@ -331,4 +344,3 @@ start_child(Index, WorkerMod, WorkerArgs, Children) ->
{error, Cause} ->
{error, Cause}
end.

2 changes: 1 addition & 1 deletion src/leo_pod_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%%
%% Leo POD
%%
%% Copyright (c) 2012-2015 Rakuten, Inc.
%% Copyright (c) 2012-2017 Rakuten, Inc.
%%
%% This file is provided to you under the Apache License,
%% Version 2.0 (the "License"); you may not use this file
Expand Down
1 change: 1 addition & 0 deletions test/leo_pod_mod.erl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ init([WorkerArgs]) ->
{ok, WorkerArgs}.

handle_call(stop,_From, State) ->
?debugVal({stop,_From}),
{stop, normal, ok, State};

handle_call({echo, Msg},_From, State) ->
Expand Down
80 changes: 52 additions & 28 deletions test/leo_pod_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ teardown(_) ->
suite_(_) ->
%% Prepare-1
PodName = 'test_worker_pod',
PodSize = 8,
PodSize = 8,
MaxOverflow = 16,
ModName = 'leo_pod_mod',
WorkerArgs = [{protocol, tcp},
{host, "127.0.0.1"},
{port, 8080}],
ModName = 'leo_pod_mod',
%% WorkerArgs = [{protocol, tcp},
%% {host, "127.0.0.1"},
%% {port, 8080}],
WorkerArgs = [],
InitFun = fun(_ManagerRef) ->
void
end,
void
end,
leo_pod:start_link(PodName, PodSize, MaxOverflow, ModName, WorkerArgs, InitFun),

%% Confirm procs #1
Expand All @@ -71,36 +72,43 @@ suite_(_) ->
%% Execute-2 - [checkout > exec > checkin]
ok = execute_2(PodSize + 2, PodName, slow_echo),
timer:sleep(100),
?assertEqual({ok, {PodSize + 2, 0, MaxOverflow - 2}}, leo_pod:status(PodName)),
timer:sleep(300),
?assertEqual({ok, {PodSize + 2, 0, 2}}, leo_pod:status(PodName)),
timer:sleep(600),
?assertEqual({ok, {0, PodSize, MaxOverflow}}, leo_pod:status(PodName)),
[?debugVal(P) || P <- erlang:processes()],

%% Prepare-2
PodName1 = 'test_worker_pod_1',
PodSize1 = 4,
MaxOverflow1 = 8,
ModName1 = 'leo_pod_mod',
WorkerArgs1 = [{protocol, tcp},
{host, "127.0.0.1"},
{port, 8080}],
leo_pod:start_link(PodName1, PodSize1, MaxOverflow1, ModName1, WorkerArgs1, InitFun),
PodName_1 = 'test_worker_pod_1',
PodSize_1 = 2,
MaxOverflow_1 = 2,
ModName_1 = 'leo_pod_mod',
WorkerArgs_1 = [],
leo_pod:start_link(PodName_1, PodSize_1, MaxOverflow_1, ModName_1, WorkerArgs_1, InitFun),

%% Confirm procs #2
?assertEqual({ok, {0, PodSize1, MaxOverflow1}}, leo_pod:status(PodName1)),
?assertEqual({ok, {0, PodSize_1, MaxOverflow_1}}, leo_pod:status(PodName_1)),

%% Execute-4 - [checkout > exec > checkin]
ok = execute_1(16, PodName1, echo),
?assertEqual({ok, {0, PodSize1, MaxOverflow1}}, leo_pod:status(PodName1)),
ok = execute_1(16, PodName_1, echo),
?assertEqual({ok, {0, PodSize_1, MaxOverflow_1}}, leo_pod:status(PodName_1)),

%% Execute-2 - [checkout > exec > checkin]
ok = execute_2(PodSize + 2, PodName_1, slow_echo),
timer:sleep(timer:seconds(1)),
?debugVal(leo_pod:status(PodName_1)),

[?debugVal(P) || P <- erlang:processes()],

%% Termination
leo_pod:stop(PodName),
leo_pod:stop(PodName1),
leo_pod:stop(PodName_1),
ok.


%% ===================================================================
%% Internal Functions
%% ===================================================================
%% @private
execute_1(0,_Name,_Fun) ->
ok;
execute_1(Index, Name, Fun) ->
Expand All @@ -113,18 +121,34 @@ execute_1(Index, Name, Fun) ->
ok = leo_pod:checkin_async(Name, Worker),
execute_1(Index - 1, Name, Fun).

%% @private
execute_2(0,_Name,_Fun) ->
ok;
execute_2(Index, Name, Fun) ->
spawn(fun() ->
{ok, Worker} = leo_pod:checkout(Name),

Msg1 = lists:append(["index_", integer_to_list(Index)]),
{ok, Msg2} = gen_server:call(Worker, {Fun, Msg1}),
?assertEqual(Msg1, Msg2),

ok = leo_pod:checkin(Name, Worker)
checkout(Index, Name, Fun, 0)
end),
execute_2(Index - 1, Name, Fun).

%% @private
checkout(Index, PodName, Fun, Times) ->
case leo_pod:checkout(PodName) of
{ok, Worker} ->
Msg1 = lists:append(["index_", integer_to_list(Index)]),
{ok, Msg2} = gen_server:call(Worker, {Fun, Msg1}),
case Times > 0 of
true ->
?debugVal({Index, {Worker, Msg2}, Times});
false ->
void
end,
?assertEqual(Msg1, Msg2),

ok = leo_pod:checkin(PodName, Worker);
{error,_Cause} ->
?debugVal({Index, _Cause, Times}),
timer:sleep(100),
checkout(Index, PodName, Fun, Times + 1)
end.

-endif.

0 comments on commit 126b320

Please sign in to comment.