Skip to content

Commit

Permalink
add global counter
Browse files Browse the repository at this point in the history
  • Loading branch information
stolen committed Jun 28, 2014
1 parent b45e5e6 commit 0f14927
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/erdico.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ stop(_) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init(root) ->
{ok, _} = start_cowboy(),
{ok, {{one_for_one, 10, 5}, []}}.
Counter = {counter, {erdico_counter, start_link, []},
permanent, 1000, worker, [erdico_counter]},
{ok, {{one_for_one, 10, 5}, [Counter]}}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Internals
Expand All @@ -37,4 +39,7 @@ start_cowboy() ->
Host = {'_', [DefPath]}, % No virtualhosts
Dispatch = cowboy_router:compile([Host]),
Env = [{env, [{dispatch, Dispatch}]}],
cowboy:start_http(?MODULE, 10, [{port, 2080}], Env).
cowboy:start_http(?MODULE, 10, [{port, conf(port, 2080)}], Env).

conf(Key, Default) ->
application:get_env(?MODULE, Key, Default).
64 changes: 64 additions & 0 deletions src/erdico_counter.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
-module(erdico_counter).

-export([start_link/0, inc/0, inc/1]).

-behavior(gen_server).
-export([init/1, handle_info/2, handle_cast/2, handle_call/3, terminate/2, code_change/3]).

%% API
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

inc() ->
inc(1).
inc(Inc) ->
Master = global:whereis_name(?MODULE),
gen_server:call(Master, {inc, Inc}).

% Start: choose role
init([]) ->
ok = global:sync(),
{ok, capture_or_monitor()}.

% Become master or monitor existing one
capture_or_monitor() ->
case global:register_name(?MODULE, self()) of
yes -> {master, 0};
no -> {slave, set_monitor()}
end.

% Monitor master
set_monitor() ->
Master = global:whereis_name(?MODULE),
erlang:monitor(process, Master).


% When master goes down, try to change him
handle_info({'DOWN', Ref, process, _Master, _Info}, {slave, Ref}) ->
{noreply, capture_or_monitor()};
% Dummy
handle_info(_, State) ->
{noreply, State}.

% Dummy
handle_cast(_, State) ->
{noreply, State}.

% When client asks to increment master's number, do it
handle_call({inc, Inc}, _From, {master, Count}) when is_integer(Inc) ->
NextCount = Count + Inc,
{reply, {ok, NextCount}, {master, NextCount}};
% Refuse to increment on slave
handle_call({inc, _}, _From, {slave, _} = State) ->
{reply, {error, slave}, State};
% Default: return error
handle_call(_, _From, State) ->
{reply, {error, not_implemented}, State}.

% Dummy
code_change(_, State, _) ->
{ok, State}.

% Dummy
terminate(_, _) ->
ok.

0 comments on commit 0f14927

Please sign in to comment.