Skip to content

Instantly share code, notes, and snippets.

@christophermaier
Last active August 29, 2015 14:20
Show Gist options
  • Save christophermaier/13c557a8d14a5ad557b5 to your computer and use it in GitHub Desktop.
Save christophermaier/13c557a8d14a5ad557b5 to your computer and use it in GitHub Desktop.
gen_fsm with gproc
{deps, [
{gproc, ".*",
{git, "https://github.com/uwiger/gproc.git", {tag, "0.3.1"}}}
]}.
-module(testfsm).
-behaviour(gen_fsm).
-define(SERVER, ?MODULE).
%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------
-export([start_link/1, scold/1, praise/1, trace/1]).
%% ------------------------------------------------------------------
%% gen_fsm Function Exports
%% ------------------------------------------------------------------
-export([init/1, happy/2, happy/3, angry/2, angry/3, find_all/0, handle_event/3,
handle_sync_event/4, handle_info/3, terminate/3,
code_change/4]).
%% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------
start_link(N) ->
gen_fsm:start_link({via, gproc, {n,l,{?MODULE, N}}}, ?MODULE, [], []).
scold(Name) ->
gen_fsm:send_event({via, gproc, {n,l,{?MODULE, Name}}}, scold).
praise(Name) ->
gen_fsm:send_event({via, gproc, {n,l,{?MODULE, Name}}}, praise).
trace(Name) ->
sys:trace(gproc:where({n,l,{?MODULE, Name}}), true).
find_all() ->
Key = {?MODULE, '_'},
GProcKey = {'_', '_', Key},
MatchHead = {GProcKey, '_', '_'},
Guard = [],
Result = ['$$'],
gproc:select([{MatchHead, Guard, Result}]).
%% ------------------------------------------------------------------
%% gen_fsm Function Definitions
%% ------------------------------------------------------------------
init(_Args) ->
{ok, happy, initial_state}.
happy(praise, State) ->
{next_state, happy, State};
happy(scold, State) ->
{next_state, angry, State}.
angry(scold, State) ->
{next_state, angry, State};
angry(praise, State) ->
{next_state, happy, State}.
happy(praise, _From, State) ->
{reply, ok, happy, State};
happy(scold, _From, State) ->
{reply, ok, angry, State}.
angry(scold, _From, State) ->
{reply, ok, angry, State};
angry(praise, _From, State) ->
{reply, ok, happy, State}.
handle_event(_Event, StateName, State) ->
{next_state, StateName, State}.
handle_sync_event(_Event, _From, StateName, State) ->
{reply, ok, StateName, State}.
handle_info(_Info, StateName, State) ->
{next_state, StateName, State}.
terminate(_Reason, _StateName, _State) ->
ok.
code_change(_OldVsn, StateName, State, _Extra) ->
{ok, StateName, State}.
%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------
erl -pa ebin -pa deps/*/ebin [master@] 9:30:35
Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Eshell V6.3 (abort with ^G)
1> application:start(gproc).
ok
2> gproc:reg({n,l,me}).
true
3>
3> testfsm:start_link(alice).
{ok,<0.44.0>}
4> testfsm:trace(alice).
ok
5> gproc:where({n,l,{testfsm,alice}}).
<0.44.0>
6>
6> testfsm:start_link(bob).
{ok,<0.48.0>}
7> testfsm:trace(bob).
ok
8> gproc:where({n,l,{testfsm,bob}}).
<0.48.0>
9>
9> testfsm:start_link(charlie).
{ok,<0.52.0>}
10> testfsm:trace(charlie).
ok
11> gproc:where({n,l,{testfsm,charlie}}).
<0.52.0>
12>
12> testfsm:praise(alice).
*DBG* {n,l,{testfsm,alice}} got event praise in state happy
*DBG* {n,l,{testfsm,alice}} switched to state happy
ok
13> testfsm:praise(bob).
*DBG* {n,l,{testfsm,bob}} got event praise in state happy
*DBG* {n,l,{testfsm,bob}} switched to state happy
ok
14> testfsm:scold(bob).
*DBG* {n,l,{testfsm,bob}} got event scold in state happy
*DBG* {n,l,{testfsm,bob}} switched to state angry
ok
15>
15> gproc:select([{'_',[],['$$']}]). %% returns the 'me' process
[[{n,l,me},<0.32.0>,undefined],
[{n,l,{testfsm,alice}},<0.44.0>,undefined],
[{n,l,{testfsm,bob}},<0.48.0>,undefined],
[{n,l,{testfsm,charlie}},<0.52.0>,undefined]]
16> testfsm:find_all(). %% returns only testfsm processes
[[{n,l,{testfsm,alice}},<0.44.0>,undefined],
[{n,l,{testfsm,bob}},<0.48.0>,undefined],
[{n,l,{testfsm,charlie}},<0.52.0>,undefined]]
17>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment