summaryrefslogtreecommitdiff
path: root/eventserv.erl
diff options
context:
space:
mode:
Diffstat (limited to 'eventserv.erl')
-rw-r--r--eventserv.erl98
1 files changed, 98 insertions, 0 deletions
diff --git a/eventserv.erl b/eventserv.erl
new file mode 100644
index 0000000..dc4dcde
--- /dev/null
+++ b/eventserv.erl
@@ -0,0 +1,98 @@
+%%%-------------------------------------------------------------------
+%%% @author Joe Zhao
+%%% @copyright (C) 2014, <COMPANY>
+%%% @doc
+%%% This module serves the purpose of registering and monitoring different events
+%%% Whether they are periodic or oneshot.
+%%% Events are happening in a sense that none should be depending on those that happend before.
+%%% Spawning one with mutable state is thus not recommended and not supported in such modules.
+%%% Thus, the events are defined so that none of them would have states change during different invocations.
+%%% @end
+%%% Created : 27. 四月 2014 19:11
+%%%-------------------------------------------------------------------
+-module(eventserv).
+-author("Joe Zhao").
+
+-include("eventserv.hrl").
+-compile([debug_info,export_all]).
+
+%% API
+%%-export([]).
+
+event(Pid,S) ->
+ receive
+ {_PPid,shutdown} ->
+ io:format("I, ~p, am killed.\n",[S#event.name])
+ after S#event.period ->
+ Pid ! {self(),run,S},
+ if
+ S#event.spawn -> spawn(S#event.call,[self()]);
+ true -> (S#event.call)(self())
+ end,
+ case S#event.type of
+ oneshot -> ok;
+ periodic -> event(Pid,S);
+ _Else -> ok
+ end
+ end.
+
+recloop(Events) ->
+ receive
+ {Pid,shutdown} -> [ Proc ! {self(),shutdown} || Proc<- orddict:fetch_keys(Events)];
+ {PPid,reg,S} ->
+ Pid = spawn(?MODULE,event,[self(),S]),
+ link(Pid),
+ recloop(orddict:store(Pid,S,Events));
+ {Pid,run,S} ->
+ io:format("Event run, type ~p: ~p\n",[S#event.type,S#event.name]),
+ recloop(Events);
+ {'EXIT',Pid,Cond} when Cond==normal;Cond==shutdown ->
+ io:format("Event died naturally, pid: ~p\n.",[Pid]),
+ recloop(orddict:erase(Pid,Events));
+ {'EXIT',Pid,Cause} ->
+ S=orddict:fetch(Pid,Events),
+ io:format("Event died abruptly(~p), pid: ~p ; name: ~p\n.",[Cause,Pid,S#event.name]),
+ if
+ S#event.type == periodic ->
+ io:format("Event(periodic) will restart, name: ~p\n.",[S#event.name]),
+ self() ! {self(),reg,S}
+ end,
+ recloop(orddict:erase(Pid,Events))
+ end.
+
+evemon(Events) ->
+ process_flag(trap_exit,true),
+ register(?MODULE,self()),
+ recloop(Events).
+
+start() ->
+ spawn(?MODULE,evemon,[orddict:new()]).
+
+reg_future(Name,Call,T) ->
+ eventserv ! {self(),reg,#event{name=Name,server=eventserv,
+ call=Call,period=T,type=oneshot}}.
+
+reg_future(Call,T) ->
+ eventserv ! {self(),reg,#event{name="Unamed",server=eventserv,
+ call=Call,period=T,type=oneshot}}.
+
+reg_periodic(Name,Call,T) ->
+ eventserv ! {self(),reg,#event{name=Name,server=eventserv,
+ call=Call,period=T}}.
+
+reg_periodic(Call,T) ->
+ eventserv ! {self(),reg,#event{name="Unamed",server=eventserv,
+ call=Call,period=T}}.
+
+regevent(Pid,S) ->
+ Pid ! {self(),reg,S}.
+
+test() ->
+ Pid=start(),
+ Pid ! {self(),reg,#event{name="test1",server=Pid,
+ call=fun (PPid) -> io:format("HAHA im here!!!!\n") end,period=1000}},
+ timer:sleep(500),
+ Pid ! {self(),reg,#event{name="test2",server=Pid,
+ call=fun (PPid) -> io:format("HAHA im away and buggy!!!!\n"),exit("I just love to die") end,period=1000}},
+ timer:sleep(10000),
+ Pid ! {self(),shutdown}. \ No newline at end of file