LiamBaisley
LiamBaisley

Reputation: 35

Azure durable function running multiple times on startup when running locally

I have an http triggered azure durable function with an orchestration trigger called "ExecuteWork" and two activities namely "HandleClaimsForms" and "HandleApplicationForms". I will add the definitions for them below. The function is used to process PDFs in a blob storage container. When running locally it will execute "HandleClaimsForms" four or five times on startup without it being called.

Here are the logs that it is producing:

Functions:

        Function1: [GET,POST] http://localhost:7071/api/Function1

        ExecuteWork: orchestrationTrigger

        HandleApplicationForms: activityTrigger

        HandleClaimsForms: activityTrigger

[2022-06-07T12:39:44.587Z] Executing 'HandleClaimsForms' (Reason='(null)', Id=c45878fe-35c8-4a57-948e-0b43da969427)
[2022-06-07T12:39:44.587Z] Executing 'HandleClaimsForms' (Reason='(null)', Id=0fb9644d-6748-4791-96cf-a92f6c161a97)
[2022-06-07T12:39:44.587Z] Executing 'HandleClaimsForms' (Reason='(null)', Id=9a39a169-a91d-4524-b5e5-63e6226f70ec)
[2022-06-07T12:39:44.587Z] Executing 'HandleClaimsForms' (Reason='(null)', Id=b3697f6b-7c96-4497-826f-3894359ff361)
[2022-06-07T12:39:44.587Z] Executing 'HandleClaimsForms' (Reason='(null)', Id=3ca3bbce-1657-453b-a5b3-e9dbdb940302)

Here are the Function definitions:

Function entrypoint

[FunctionName("Function1")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            [DurableClient] IDurableOrchestrationClient starter,
            ILogger log)
        {
            string instanceID = await starter.StartNewAsync("ExecuteWork");

            return starter.CreateCheckStatusResponse(req, instanceID);
        }

Orchestration trigger

[FunctionName("ExecuteWork")]
        public async Task<bool> ProcessForms(
            [OrchestrationTrigger] IDurableOrchestrationContext context,
            ILogger log)
        {
            bool success = true;
            try
            {
                await context.CallActivityAsync("HandleClaimsForms", success);
                await context.CallActivityAsync("HandleApplicationForms", success);

                return success;
            }
            catch (Exception err)
            {
                log.LogInformation($"The following error was thrown: {err}");
                success = false;
                return success;
            }
        }

HandleClaimsForm Activity

        public async Task<bool> ProcessClaimsForms(
            [ActivityTrigger]bool success)
        {

                await _docHandler.Handle();

                return success;
        }

HandleApplicationForm activity

[FunctionName("HandleApplicationForms")]
        public async Task<bool> ProcessApplicationForms(
            [ActivityTrigger]bool success)
        {

            await _appHandler.HandleJsonApplicationFormAsync();

            return success;
        }

Upvotes: 0

Views: 3903

Answers (1)

AjayKumarGhose
AjayKumarGhose

Reputation: 4923

One of the workaround you can follow to resolve the above issue,

Based on the MICROSOFT DOCUMENT about the reliability is:

  • Durable Functions uses event sourcing transparently. Behind the scenes, the await (C#) or yield (JavaScript/Python) operator in an orchestrator function yields control of the orchestrator thread back to the Durable Task Framework dispatcher.

  • The orchestrator wakes up and re-executes the entire function from scratch to rebuild the local state whenever an orchestration function is given more work to do (for instance, when a response message is received or a durable timer expires). The Durable Task Framework analyses the orchestration's execution history if the code tries to invoke a function or do any other async task during the replay. In the event that it discovers that the activity function has already run and produced a result, it replays that result while the orchestrator code keeps running. Playback continues until the function code terminates or until additional async work has been scheduled.

Another, approach is to use the dependency injection .

For more information please refer the below links:-

Upvotes: 1

Related Questions