Skip to content

Instantly share code, notes, and snippets.

@ToJans
Last active December 17, 2015 14:19
Show Gist options
  • Save ToJans/5623763 to your computer and use it in GitHub Desktop.
Save ToJans/5623763 to your computer and use it in GitHub Desktop.
A bus thath generates a process per AR instance and sends messages to it
-module(bus).
-compile(export_all).
% Public interface
start(RouteResolver) ->
Pid = spawn_link(?MODULE,loop,{RouteResolver,dict:new()}),
register(bus,Pid).
stop() ->
bus ! quit.
send(Message) ->
bus ! Message.
%% private stuff
loop({RouteResolver,ActiveProcesses}) ->
receive
quit ->
terminate_self_and_kill_siblings(ActiveProcesses);
Message ->
Routes = RouteResolver(Message),
ActiveProcesses1 = process_message_on_routes(Routes,Message,ActiveProcesses),
loop({RouteResolver,ActiveProcesses1})
end.
terminate_self_and_kill_siblings(ActiveProcesses) ->
[P ! {quit} || {_,P} <- dict:to_list(ActiveProcesses)],
io:format("Terminating ~s~n",[?MODULE]).
process_message_on_routes([],_Message,ActiveProcesses) ->
ActiveProcesses;
process_message_on_routes([Route|T],Message,ActiveProcesses) ->
ActiveProcesses1 = process_message_on_route(Route,Message,ActiveProcesses),
process_message_on_routes(T,Message,ActiveProcesses1).
process_message_on_route(Key,Message,ActiveProcesses) ->
{Pid,ActiveProcesses1} = get_handler_instance_pid_for_key(Key,ActiveProcesses),
Pid ! Message,
ActiveProcesses1.
get_handler_instance_pid_for_key(Key,ActiveProcesses) ->
get_handler_instance_pid_for_key_or_create_it(dict:find(Key),Key,ActiveProcesses).
get_handler_instance_pid_for_key_or_create_it({ok, Pid},_Key,ActiveProcesses) ->
{Pid,ActiveProcesses};
get_handler_instance_pid_for_key_or_create_it(error,{Module,Id},ActiveProcesses) ->
Pid = spawn(Module,start,[Id]),
ActiveProcesses1 = dict:append({Module,Id},Pid,ActiveProcesses),
{Pid,ActiveProcesses1}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment