public async Task <SignerResult> WaitForSign( [OrchestrationTrigger] IDurableOrchestrationContext context) { WaitForSignParameters input = context.GetInput <WaitForSignParameters>(); // Update this sub-orchestrator data to DB so event can be sent to this instance // Note this could also be done differently; // We could define the instance id in the parent orchestrator and store it in DB there await context.CallActivityAsync(nameof(SetEventOrchestratorInfo), new SetEventOrchestratorInfoParameters { InstanceId = context.InstanceId, RequestId = input.RequestId, SignerEmail = input.SignerEmail }); try { // Wait for user to sign for 5 days // Note this does not actually make the function wait here for 5 days // The function is completely suspended until something happens // You can't put more than 6 days of wait time here though // Leaving out the timeout makes the wait _indefinite_ SigningEvent ev = await context.WaitForExternalEvent <SigningEvent>(SignEvent, TimeSpan.FromDays(5)); if (ev.Email != input.SignerEmail) { throw new Exception("Wrong signer"); } // Update decision info to DB await context.CallActivityAsync(nameof(SetSigningDataForSigner), new SetSigningDataForSignerParameters { RequestId = input.RequestId, SignerEmail = input.SignerEmail, Signed = ev.Signed, DecidedAt = ev.DecidedAt }); return(new SignerResult { Result = ev.Signed ? SigningDecision.Signed : SigningDecision.Rejected, SignerEmail = input.SignerEmail, DecidedAt = ev.DecidedAt }); } catch (TimeoutException) { // User did not respond within 5 days return(new SignerResult { Result = SigningDecision.Expired, DecidedAt = context.CurrentUtcDateTime, SignerEmail = input.SignerEmail }); // Note above we get the current time from the context // This is important since orchestrators must be _deterministic_ // DateTimeOffset.UtcNow is not deterministic since the value is different on each run // CurrentUtcDateTime is derived from the history table used by Durable Functions } }
public async Task <HttpResponseMessage> AddSignEvent( [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestMessage req, [DurableClient] IDurableOrchestrationClient orchestrationClient, ILogger log) { AddSignEventModel model = await req.Content.ReadAsAsync <AddSignEventModel>(); string instanceId = model.InstanceId; SigningEvent eventData = model.EventData; await orchestrationClient.RaiseEventAsync(instanceId, SignEvent, eventData); log.LogInformation("Sign event raised to instance {InstanceId}", instanceId); return(req.CreateResponse(HttpStatusCode.NoContent)); }