I recently upgraded to the isolated NET7 Azure Functions worker. Durable Function's API has changed quiete a bit in with that, but it is GA now.
I need to get the orchestration's instance id
from within the activity function. Previously (with the in-process model), I was able to inject the IDurableActivityContext interface
in the function and reference the instance id from there.
Afaik, the equivalent now is the TaskActivityContext class
. However, if I inject this into the function it is always null.
How to get it? I could just pass it as an input from the orchestrator. But I would not prefer this.
namespace MyNamespace;
public class TestActionable
{
private readonly ILogger _log;
public TestActionable(ILogger<TestActionable> log) => _log = log;
[Function("TestActionable_Trigger")]
public async Task TriggerWorkflow([DurableClient] DurableTaskClient client,
[QueueTrigger(QueueNames.ACTIONABLE_TEST, Connection = BindingConnectionNames.MY_BINDINGNAME)]string q)
{
var now = DateTimeOffset.UtcNow.ToIsoString();
_log.LogWarning("Triggering workflow now");
await client.ScheduleNewOrchestrationInstanceAsync("TestActionable_Workflow", input: now);
_log.LogWarning("Triggered");
}
[Function("TestActionable_Workflow")]
public static async Task RunWorkflow([OrchestrationTrigger] TaskOrchestrationContext ctx)
{
var log = ctx.CreateReplaySafeLogger("TestActionable_Workflow");
log.LogWarning("Workflow started with input= {input}", ctx.GetInput<string>());
var input = new { a=1337 };
var output = await ctx.CallActivityAsync<bool>("TestActionable_Activity", input);
log.LogWarning("Activity completed successfully= {output}", output);
log.LogWarning("Workflow complete");
}
[Function("TestActionable_Activity")]
public async Task<bool> RunActivity([ActivityTrigger] object input, TaskActivityContext ctx)
{
_log.LogWarning("Started activity, input= {i}", input);
if (ctx is null)
{
_log.LogError("TaskActivityContext is null");
return false;
}
_log.LogWarning("TaskActivityContext= {ctx}", ctx.Serialize());
_log.LogWarning("The orchestration's instance id is= {ctx}", ctx.InstanceId);
_log.LogWarning("Waited 1s, activity complete");
await Task.Delay(1000);
return true;
}
}
Here's the log output
[2023-03-03T08:03:01.668Z] Executing 'Functions.TestActionable_Trigger' (Reason='New queue message detected on 'actionable-test'.', Id=1cc9891b-85a4-4dd4-90e2-19417cc7519a)
[2023-03-03T08:03:01.674Z] Trigger Details: MessageId: ae725935-4b5c-4299-ac48-44f1af934363, DequeueCount: 1, InsertedOn: 2023-03-03T08:03:00.000+00:00
[2023-03-03T08:03:01.863Z] Host lock lease acquired by instance ID '00000000000000000000000041F3D3B5'.
[2023-03-03T08:03:02.192Z] Scheduling new TestActionable_Workflow orchestration with instance ID '388c8c6c4f554f49ac1d9f50ac747e9b' and 28 bytes of input data.
[2023-03-03T08:03:02.192Z] Triggering workflow now
[2023-03-03T08:03:02.648Z] Triggered
[2023-03-03T08:03:02.757Z] Executed 'Functions.TestActionable_Trigger' (Succeeded, Id=1cc9891b-85a4-4dd4-90e2-19417cc7519a, Duration=1152ms)
[2023-03-03T08:03:06.020Z] Executing 'Functions.TestActionable_Workflow' (Reason='(null)', Id=0e4c510b-78c9-4e3a-8e9a-8f3cef8b4eb5)
[2023-03-03T08:03:06.213Z] Workflow started with input= 2023-03-03T08:03:02.12594Z
[2023-03-03T08:03:06.333Z] Executed 'Functions.TestActionable_Workflow' (Succeeded, Id=0e4c510b-78c9-4e3a-8e9a-8f3cef8b4eb5, Duration=358ms)
[2023-03-03T08:03:06.498Z] Executing 'Functions.TestActionable_Activity' (Reason='(null)', Id=07db96ca-df51-41e2-9906-e7012d7f2eda)
[2023-03-03T08:03:06.533Z] Started activity, input= {"a":1337}
[2023-03-03T08:03:06.533Z] TaskActivityContext is null
[2023-03-03T08:03:06.548Z] Executed 'Functions.TestActionable_Activity' (Succeeded, Id=07db96ca-df51-41e2-9906-e7012d7f2eda, Duration=56ms)
[2023-03-03T08:03:06.692Z] Executing 'Functions.TestActionable_Workflow' (Reason='(null)', Id=edde658a-c820-41bb-8d09-cc13ca14040d)
[2023-03-03T08:03:06.721Z] Activity completed successfully= False
[2023-03-03T08:03:06.721Z] Workflow complete
[2023-03-03T08:03:06.739Z] Executed 'Functions.TestActionable_Workflow' (Succeeded, Id=edde658a-c820-41bb-8d09-cc13ca14040d, Duration=52ms)
Apparently, this is by design. As noted here there is no equivalent in the isolated worker for DurableActivityContext
. The TaskActivityContext
I mentioned in my question, and which I figured to be the replacement for what I need (which it is not), appears to be only usable with the new approach of writing durable functions code, see class-based.