Last active
April 15, 2021 06:55
-
-
Save laur3d/1bd51250c866fcfaa8246f88641f4e70 to your computer and use it in GitHub Desktop.
Dynamic Orchestrator
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
public static class FlowMaker | |
{ | |
[FunctionName("FlowMaker")] | |
public static async Task<int> Run([OrchestrationTrigger] IDurableOrchestrationContext context) | |
{ | |
// imagine this comes from a DB or the request payload | |
var steps = new DynamicFlowContext | |
{ | |
Steps = new List<DynamicStep<int>> | |
{ | |
new DynamicStep<int>(ActionName.Add, 1, 1), | |
new DynamicStep<int>(ActionName.Add, 1), | |
new DynamicStep<int>(ActionName.Subtract, 1), | |
new DynamicStep<int>(ActionName.Multiply, 10) | |
} | |
}; | |
var result = await context.CallSubOrchestratorAsync<DynamicResult<int>>("DynamicOrchestrator", steps); | |
return result.Result; | |
} | |
[FunctionName("DynamicOrchestrator")] | |
public static async Task<DynamicResult<int>> RunInnerOrchestrator([OrchestrationTrigger] IDurableOrchestrationContext ctx) | |
{ | |
var input = ctx.GetInput<DynamicFlowContext>(); | |
int state = 0; | |
foreach (var step in input.Steps) | |
{ | |
state = await ctx.CallActivityAsync<int>(step.Action, (state, step.param)); | |
} | |
return new DynamicResult<int> | |
{ | |
Result = state | |
}; | |
} | |
[FunctionName("Add")] | |
public static async Task<int> Add([ActivityTrigger] (int a, int b) numbers, ILogger log) | |
{ | |
return numbers.a + numbers.b; | |
} | |
[FunctionName("Subtract")] | |
public static async Task<int> Subtract([ActivityTrigger] (int a, int b) numbers, ILogger log) | |
{ | |
return numbers.a - numbers.b; | |
} | |
[FunctionName("Multiply")] | |
public static async Task<int> Multiply([ActivityTrigger] (int a, int b) numbers, ILogger log) | |
{ | |
return numbers.a * numbers.b; | |
} | |
[FunctionName("Divide")] | |
public static async Task<int> Divide([ActivityTrigger] (int a, int b) numbers, ILogger log) | |
{ | |
return numbers.a / numbers.b; | |
} | |
[FunctionName("FlowMaker_HttpStart")] | |
public static async Task<HttpResponseMessage> HttpStart( | |
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "start")] | |
HttpRequestMessage req, | |
[DurableClient] IDurableOrchestrationClient starter, | |
ILogger log) | |
{ | |
// Function input comes from the request content. | |
string instanceId = await starter.StartNewAsync("FlowMaker"); | |
log.LogInformation($"Started orchestration with ID = '{instanceId}'."); | |
return starter.CreateCheckStatusResponse(req, instanceId); | |
} | |
public class DynamicFlowContext{ | |
public List<DynamicStep<int>> Steps { get; set; } | |
} | |
} | |
public class DynamicStep<T> | |
{ | |
public string Action { get; private set; } | |
public T param { get; private set; } | |
[JsonConstructor] | |
public DynamicStep(string action, T param) | |
{ | |
Action = action; | |
this.param = param; | |
} | |
} | |
public class DynamicResult<T> | |
{ | |
public T Result { get; set; } | |
} | |
public static class ActionName | |
{ | |
public const string Add = "Add"; | |
public const string Subtract = "Subtract"; | |
public const string Multiply = "Multiply"; | |
public const string Divide = "Divide"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment