Last active
August 29, 2015 13:57
-
-
Save ahammel/9697575 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| The foo system consists of a master process, a supervisor, and some worker | |
| processes. The worker processes do a computationally expensive thing and send | |
| the results to the master process, which then maybe asks the supervisor to | |
| spawn more workers, depending on the result: | |
| ################ asks for workers... #################### | |
| # foo_master # ------------------------> # foo_supervisor # --\ | |
| ################ #################### | | |
| ^ | spawns.... | |
| | | | |
| | ################ | | |
| \--------------------------------- # foo_worker # <-----/ | |
| sends results... ################ | |
| I'm trying to figure out the nicest way to encode the message passing/spawning | |
| loop without making a mess of the dependencies graph or resorting to naked | |
| message passing. An API module for the entire foo system could do that, but it | |
| seems like that module might be a bit awkward and 'know too much' about the | |
| entire system, so to speak. If I wanted to change foo_master from a gen_server | |
| to a gen_fsm, for instance, the foo_api module would probably have to change | |
| as well. |
This file contains hidden or 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
| -module(foo_master). | |
| -behaviour(gen_server). | |
| -export([start_link/1, init/1, handle_call/3]). | |
| start_link(SupervisorPid) -> | |
| gen_server:start_link(?MODULE, [SupervisorPid], []). | |
| init([SupervisorPid]) -> | |
| State = {some_stuff, SupervisorPid}, | |
| {ok, State}. | |
| handle_call(Message, _From, State) -> | |
| maybe_submit_more_jobs(Message, State), | |
| {noreply, State}. | |
| maybe_submit_more_jobs(Message, {SomeData, SupervisorPid}) -> | |
| case some_complicated_condition(Message, SomedData) of | |
| true -> submit(more_jobs, SupervisorPid); | |
| false -> die(horribly) | |
| end. | |
| %%% ============================================================ %%% | |
| submit(Jobs, SupervisorPid) -> | |
| supervisor:start_child(SupervisorPid, [some_data, self()]). % Evil? | |
| foo_worker_api:start(SupervisorPid, [some_data, self()]). % Circular dependency? | |
| foo_api:start_worker(SupervisorPid, [some_data, self()]). % Seems awkward? |
This file contains hidden or 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
| -module(foo_supervisor). | |
| -behaviour(supervisor). | |
| % Supervisor callbacks | |
| -export([start_link/1, init/1]). | |
| start_link([]) -> | |
| supervisor:start_link(?MODULE, []). | |
| init([]) -> | |
| MaxRestart = 1, | |
| MaxTime = 3600, | |
| {ok, {{simple_one_for_one, MaxRestart, MaxTime}, | |
| [{sar, | |
| {sar, start_link, []}, | |
| transient, | |
| brutal_kill, | |
| worker, | |
| [sar]}]}}. |
This file contains hidden or 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
| -module(foo_worker). | |
| -behaviour(gen_server). | |
| % Gen_server callbacks | |
| -export([start_link/2, init/1, | |
| handle_call/3, handle_cast/2, handle_info/2, | |
| terminate/2, code_change/3]). | |
| start_link(SomeData, MasterPid) -> | |
| gen_server:start_link(?MODULE, {SomeData, MasterPid}, []). | |
| init({SomeData, MasterPid}) -> | |
| gen_server:cast(?MODULE, do_some_analysis), | |
| State = {SomeData, MasterPid}, | |
| {ok, State}. | |
| handle_cast(do_some_analysis, {SomeData, MasterPid}) -> | |
| Result = analyse(SomeData), | |
| send(Result, MasterPid), | |
| {stop, normal, State}. | |
| %%% ============================================================ %%% | |
| send(Result, MasterPid) -> | |
| gen_server:call(MasterPid, Result). % Evil? | |
| foo_master_api:send(MasterPid, Result). % Circular dependency? | |
| foo_api:send_to_master(MasterPid, Result). % Seems awkward? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment