Created
October 17, 2016 03:43
-
-
Save SLIB53/4e4eb8b96a7c16112c4a1889ece5ecd7 to your computer and use it in GitHub Desktop.
This is an example of something like a linear data flow machine. The demo illustrates how to clearly implement a sequence of linear steps so that each step is is similarly handled. This pattern is useful for orchestrating a high level steps, such as a sequence of calls to other services in a "serverless" application.
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
% This is an example of something like a linear data flow machine. The demo | |
% illustrates how to clearly implement a sequence of linear steps so that each | |
% step is is similarly handled. This pattern is useful for orchestrating a high | |
% level steps, such as a sequence of calls to other services in a "serverless" | |
% application. | |
-module(data_sequence). | |
-export([demo/0]). | |
demo() -> | |
DemoSequence = [ | |
{<<"Step 1">>, fun ok_demo_step/1}, | |
{<<"Step 2">>, fun error_demo_step/1} | |
], | |
execute(DemoSequence, [], fun demo_error_effects/3, fun demo_crash_effects/3). | |
demo_error_effects({StepName, _StepFun} = _Step, _Buffer, {Error, Reason}) -> | |
io:format("Step>~p failed! Error>~p Reason>~p Discontinuing sequence...~n", | |
[StepName, Error, Reason]), | |
ok. | |
demo_crash_effects({StepName, _StepFun} = _Step, _Buffer, {Error, Reason}) -> | |
io:format("Step>~p crashed! Error>~p Reason>~p Discontinuing sequence...~n", | |
[StepName, Error, Reason]), | |
ok. | |
%%------------------------------------------------------------------------------ | |
%% Steps | |
%%------------------------------------------------------------------------------ | |
ok_demo_step(Buffer) -> | |
io:format("Pretending to do work...~n"), | |
timer:sleep(3000), | |
io:format("Did so much work.~n"), | |
{ok, Buffer}. | |
error_demo_step(_Buffer) -> | |
io:format("Doing some bad work...~n"), | |
not_a_real_module:f(). | |
%%------------------------------------------------------------------------------ | |
%% Data Sequencer | |
%%------------------------------------------------------------------------------ | |
execute(Sequence, Input, ErrorEffectsCallback, CrashEffectsCallback) -> | |
SequenceNames = [Name || {Name, _} <- Sequence], | |
io:format("Running sequence:~p ...~n~n", | |
[SequenceNames]), | |
execution_handler(Sequence, Input, ErrorEffectsCallback, CrashEffectsCallback). | |
execution_handler([], Buffer, _ErrorEffectsCallback, _CrashEffectsCallback) -> | |
{ok, Buffer}; | |
execution_handler([{StepName, StepFun} = Step | RemainingSteps], | |
Buffer, | |
ErrorEffectsCallback, | |
CrashEffectsCallback) -> | |
try | |
io:format("Running step ~p ...~n", [StepName]), | |
case apply(StepFun, [Buffer]) of | |
{ok, NewBuffer} -> | |
io:format("Completed step: ~p.~n~n", [StepName]), | |
execution_handler(RemainingSteps, | |
NewBuffer, | |
ErrorEffectsCallback, | |
CrashEffectsCallback); | |
{error, _} = E -> | |
apply(ErrorEffectsCallback, [Step, Buffer, E]), | |
{error, Buffer} | |
end | |
catch | |
Error:Reason -> | |
apply(CrashEffectsCallback, [Step, Buffer, {Error, Reason}]), | |
{error, Buffer} | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment