Created
April 15, 2011 15:47
-
-
Save RJ/921918 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% Just stores an in #state{} | |
-module(leadertest). | |
-behaviour(gen_leader). | |
%% API | |
-export([start_link/1, start_link/2, get_num/0, set_num/1, info/0]). | |
%% gen_leader callbacks | |
-export([init/1, | |
handle_cast/3, | |
handle_call/4, | |
handle_info/2, | |
handle_leader_call/4, | |
handle_leader_cast/3, | |
handle_DOWN/3, | |
elected/3, | |
surrendered/3, | |
from_leader/3, | |
code_change/4, | |
terminate/2]). | |
-define(SERVER, ?MODULE). | |
-record(state, {num}). | |
%%%=================================================================== | |
%%% API | |
%%%=================================================================== | |
%%-------------------------------------------------------------------- | |
%% @doc | |
%% Starts the server | |
%% | |
%% @spec start_link() -> {ok, Pid} | ignore | {error, Error} | |
%% @end | |
%%-------------------------------------------------------------------- | |
start_link(Nodes) -> | |
start_link(Nodes, []). | |
start_link(Nodes, Seed) when is_list(Nodes), is_atom(Seed) -> | |
start_link(Nodes, {seed_node, Seed}); | |
start_link(Nodes, Opts) -> | |
gen_leader:start_link(?SERVER, Nodes, Opts, ?MODULE, [], []). | |
get_num() -> | |
gen_leader:call(?SERVER, get_num). | |
set_num(N) -> | |
gen_leader:leader_call(?SERVER, {set_num, N}). | |
info() -> | |
gen_leader:leader_call(?SERVER, info). | |
%%%=================================================================== | |
%%% gen_leader callbacks | |
%%%=================================================================== | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Initializes the server | |
%% | |
%% @spec init(Args) -> {ok, State} | | |
%% ignore | | |
%% {stop, Reason} | |
%% @end | |
%%-------------------------------------------------------------------- | |
init([]) -> | |
{ok, #state{num=0}}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Called only in the leader process when it is elected. The Synch | |
%% term will be broadcasted to all the nodes in the cluster. | |
%% | |
%% @spec elected(State, Election, undefined) -> {ok, Synch, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
elected(State, _Election, undefined) -> | |
Sync = foo1, | |
io:format("elected! broadcasting sync:~p~n", [Sync]), | |
{ok, Sync, State}; | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Called only in the leader process when a new candidate joins the | |
%% cluster. The Synch term will be sent to Node. | |
%% | |
%% @spec elected(State, Election, Node) -> {ok, Synch, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
elected(State, _Election, Node) -> | |
io:format("new candidate ~p joined cluster, sending them num~n", [Node]), | |
Sync = State#state.num, | |
{reply, Sync, State}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Called in all members of the cluster except the leader. Synch is a | |
%% term returned by the leader in the elected/3 callback. | |
%% | |
%% @spec surrendered(State, Sync, Election) -> {ok, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
surrendered(State, Sync, _Election) -> | |
io:format("surrendered. leader sent this sync to us: ~p~n", [Sync]), | |
{ok, State#state{num=Sync}}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling call messages. Called in the leader. | |
%% | |
%% @spec handle_leader_call(Request, From, State, Election) -> | |
%% {reply, Reply, Broadcast, State} | | |
%% {reply, Reply, State} | | |
%% {noreply, State} | | |
%% {stop, Reason, Reply, State} | | |
%% {stop, Reason, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
handle_leader_call(info, _From, State, Election) -> | |
Ret = [ | |
{candidates, gen_leader:candidates(Election)}, | |
{leader_node, gen_leader:leader_node(Election)}, | |
{workers, gen_leader:workers(Election)} | |
], | |
{reply, Ret, State}; | |
handle_leader_call({set_num, N}, _From, State, _Election) -> | |
io:format("leader call~n", []), | |
{reply, ok, {set_n, N}, State#state{num=N}}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling cast messages. Called in the leader. | |
%% | |
%% @spec handle_leader_cast(Request, State, Election) -> | |
%% {ok, Broadcast, State} | | |
%% {noreply, State} | | |
%% {stop, Reason, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
handle_leader_cast(_Request, State, _Election) -> | |
{noreply, State}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling messages from leader. | |
%% | |
%% @spec from_leader(Request, State, Election) -> | |
%% {ok, State} | | |
%% {noreply, State} | | |
%% {stop, Reason, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
from_leader({set_n, N} = Sync, State, _Election) -> | |
io:format("~p Got this from the leader:~p~n", [self(), Sync]), | |
{ok, State#state{num=N}}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling nodes going down. Called in the leader only. | |
%% | |
%% @spec handle_DOWN(Node, State, Election) -> | |
%% {ok, State} | | |
%% {ok, Broadcast, State} | | |
%% @end | |
%%-------------------------------------------------------------------- | |
handle_DOWN(Node, State, _Election) -> | |
io:format("i'm the leader, and this node just went down: ~p~n", [Node]), | |
{ok, State}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling call messages | |
%% | |
%% @spec handle_call(Request, From, State, Election) -> | |
%% {reply, Reply, State} | | |
%% {noreply, State} | | |
%% {stop, Reason, Reply, State} | | |
%% {stop, Reason, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
handle_call(get_num, _From, State, _Election) -> | |
io:format("normal call~n", []), | |
Ret = State#state.num, | |
{reply, Ret, State}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling cast messages | |
%% | |
%% @spec handle_cast(Msg, State, Election) -> | |
%% {noreply, State} | | |
%% {stop, Reason, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
handle_cast(_Msg, State, _Election) -> | |
{noreply, State}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Handling all non call/cast messages | |
%% | |
%% @spec handle_info(Info, State) -> {noreply, State} | | |
%% {stop, Reason, State} | |
%% @end | |
%%-------------------------------------------------------------------- | |
handle_info(_Info, State) -> | |
{noreply, State}. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% This function is called by a gen_leader when it is about to | |
%% terminate. It should be the opposite of Module:init/1 and do any | |
%% necessary cleaning up. When it returns, the gen_leader terminates | |
%% with Reason. The return value is ignored. | |
%% | |
%% @spec terminate(Reason, State) -> void() | |
%% @end | |
%%-------------------------------------------------------------------- | |
terminate(_Reason, _State) -> | |
ok. | |
%%-------------------------------------------------------------------- | |
%% @private | |
%% @doc | |
%% Convert process state when code is changed | |
%% | |
%% @spec code_change(OldVsn, State, Election, Extra) -> | |
%% {ok, NewState} | | |
%% {ok, NewState, NewElection} | |
%% @end | |
%%-------------------------------------------------------------------- | |
code_change(_OldVsn, State, _Election, _Extra) -> | |
{ok, State}. | |
%%%=================================================================== | |
%%% Internal functions | |
%%%=================================================================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment