Skip to content

Instantly share code, notes, and snippets.

@kevsmith
Created January 30, 2009 21:41
Show Gist options
  • Save kevsmith/55274 to your computer and use it in GitHub Desktop.
Save kevsmith/55274 to your computer and use it in GitHub Desktop.
-module(node_mgr).
-behaviour(gen_server).
%% API
-export([start_link/0, register/1, next_worker/0]).
-define(SERVER, ?MODULE).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-record(state,
{nodes=[],
lookaside=[]}).
start_link() ->
gen_server:start_link({global, ?SERVER}, ?MODULE, [], []).
register(WorkerPid) ->
gen_server:call({global, ?SERVER}, {register_worker, WorkerPid}).
next_worker() ->
gen_server:call({global, ?SERVER}, next_worker).
init([]) ->
{ok, #state{}}.
handle_call({register_worker, WorkerPid}, _From, State) ->
link(WorkerPid),
{reply, ok, State#state{nodes=[WorkerPid|State#state.nodes]}};
handle_call(next_worker, _From, State) when length(State#state.nodes) > 0 ->
[NextWorker|T] = State#state.nodes,
{reply, NextWorker, State#state{nodes=T, lookaside=[NextWorker|State#state.lookaside]}};
handle_call(next_worker, _From, State) ->
NewState = State#state{nodes=State#state.lookaside, lookaside=[]},
[NextWorker|T] = NewState#state.nodes,
{reply, NextWorker, State#state{nodes=T, lookaside=[NextWorker|State#state.lookaside]}};
handle_call(_Request, _From, State) ->
{reply, ignored, State}.
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info({'EXIT', From, _Reason}, State) ->
#state{nodes=Nodes, lookaside=Lookaside} = State,
{noreply, State#state{nodes=filter_worker(From, Nodes), lookaside=filter_worker(From, Lookaside)}};
handle_info(_Info, State) ->
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% Internal functions
filter_worker(WorkerPid, Workers) ->
lists:filter(fun(WP) -> (WP =:= WorkerPid) == false end, Workers).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment