Prevent Duplicate Invocations of Durable Functions Using Azure Functions With C#
Prevent Duplicate Invocations of Durable Functions Using Azure Functions With C#
Durable Functions is an extension for Azure Functions to help write stateful services in a stateless environment. When starting a new process, you may want to verify it isn’t already running by checking the list of in-flight Durable Functions with some custom logic.
Durable Functions includes functionality to Query all instances which can help us.
Note: With many in-flight Durable Functions this approach could be problematic by needing to query many pages of results.
Code
Here’s a starting point to work from, copy and edit as needed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace MyApplication
{
public class Api
{
[FunctionName("Initiate")]
public async Task<HttpResponseMessage> Initiate(
[HttpTrigger(AuthorizationLevel.User, "post", Route = "my/route")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient client)
{
string listContinuationToken = null;
do
{
var currentInstances = await client.ListInstancesAsync(
new OrchestrationStatusQueryCondition
{
ContinuationToken = listContinuationToken,
RuntimeStatus = new[]
{
OrchestrationRuntimeStatus.ContinuedAsNew,
OrchestrationRuntimeStatus.Pending,
OrchestrationRuntimeStatus.Running
}
},
CancellationToken.None);
var alreadyRunning = currentInstances.DurableOrchestrationState
.Any(x => /* Logic here */);
if (alreadyRunning)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent("This process is currently running.")
};
}
listContinuationToken = currentInstances.ContinuationToken;
}
while (listContinuationToken != null);
var instanceId = await client.StartNewAsync("BeginProcess");
return client.CreateCheckStatusResponse(req, instanceId);
}
[FunctionName("BeginProcess")]
public async Task<IEnumerable<string>> BeginProcess(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
// Code here
}
}
}
This post is licensed under CC BY 4.0 by the author.