Azure / azure-functions-eventhubs-extension

Event Hubs extension for Azure Functions
MIT License
20 stars 26 forks source link

Using single dispatch, extension sometimes logs incorrect trigger details #114

Closed hossam-nasr closed 3 months ago

hossam-nasr commented 2 years ago

Summary

If using single dispatch, this is a bug in which the extension would sometimes log the incorrect trigger details of the EH message.

This is because, regardless of whether the user specified single dispatch or batch processing, the extension request a batch from the EH SDK regardless. However, in the case of a single dispatch, the extension loops over each message in the batch, and dispatches a new execution for each one.

However, the way it does that is that it first creates an EventHubTriggerInput object, which is created by calling GetSingleEventTriggerInput, which, instead of creating an object with just a singular event, creates a data object with the Events property set to all the events received in the batch. This data structure is properly used during executing user code to execute only on the individual message. However, in the case of logging, if it's a single dispatch, we always just log the details of the first event in the Events property, which will be the same for all events in the batch.

What this means is that, e.g., if a batch of 4 unique events is received from the SDK, and single dispatch is being used, user code will run 4 times, processing each message once, but there will be 4 identical log statements, logging the details of the first event in the batch, and also incorrectly logging the Count as 4 instead of 1.

Repro

  1. Create an EventHub
  2. Create a backlog of 4 event in the EventHub, for example by sending messages through the ServiceBusExplorer
  3. Create a single dispatch EventHub-triggered function on the EventHub you just created, logging details of the message received:
 public static class EventHubTrigger1
    {
        [FunctionName("EventHubTrigger1")]
        public static void Run([EventHubTrigger("webjobstesthub", Connection ="eventHubConnection")] EventData myEventHubMessage, DateTime enqueuedTimeUtc, Int64 sequenceNumber, string offset, ILogger log)
        {
            log.LogInformation($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
            log.LogInformation($"EnqueuedTimeUtc={enqueuedTimeUtc}");
            log.LogInformation($"SequenceNumber={sequenceNumber}");
            log.LogInformation($"Offset={offset}");
        }
    }
  1. Run your function

Expected Behavior

In the logs, I expect to see unique TriggerDetails: ... log for each execution with unique offset, enqueue time, sequence number, that match those I log from inside my function.

Actual Behavior

Logs of the trigger details are identical for all messages in the batch, and are mismatched from logs from inside my function. For example:

[2022-07-26T22:54:43.427Z] Executing 'EventHubTrigger1' (Reason='(null)', Id=6724dd37-3c3f-4676-bffb-ebb94888506b)
[2022-07-26T22:54:43.429Z] Trigger Details: PartionId: 0, Offset: 2800, EnqueueTimeUtc: 2022-07-26T22:54:15.5200000Z, SequenceNumber: 22, Count: 4
[2022-07-26T22:54:43.430Z] Event: message 1
[2022-07-26T22:54:43.431Z] EnqueuedTimeUtc=7/26/2022 10:54:15 PM
[2022-07-26T22:54:43.432Z] Executing 'EventHubTrigger1' (Reason='(null)', Id=aec42a41-8093-4f61-b586-f03aec0fb26b)
[2022-07-26T22:54:43.432Z] SequenceNumber=22
[2022-07-26T22:54:43.433Z] Trigger Details: PartionId: 0, Offset: 2800, EnqueueTimeUtc: 2022-07-26T22:54:15.5200000Z, SequenceNumber: 22, Count: 4
[2022-07-26T22:54:43.433Z] Offset=2800
[2022-07-26T22:54:43.434Z] Executing 'EventHubTrigger1' (Reason='(null)', Id=9064dbdc-7bee-4353-9b98-253fa0820f2b)
[2022-07-26T22:54:43.434Z] Event: message 2
[2022-07-26T22:54:43.435Z] Trigger Details: PartionId: 0, Offset: 2800, EnqueueTimeUtc: 2022-07-26T22:54:15.5200000Z, SequenceNumber: 22, Count: 4
[2022-07-26T22:54:43.436Z] EnqueuedTimeUtc=7/26/2022 10:54:18 PM
[2022-07-26T22:54:43.437Z] Executing 'EventHubTrigger1' (Reason='(null)', Id=b36aaf91-f23a-484e-abfb-025540e43b3c)
[2022-07-26T22:54:43.437Z] SequenceNumber=23
[2022-07-26T22:54:43.438Z] Trigger Details: PartionId: 0, Offset: 2800, EnqueueTimeUtc: 2022-07-26T22:54:15.5200000Z, SequenceNumber: 22, Count: 4
[2022-07-26T22:54:43.438Z] Offset=2912
[2022-07-26T22:54:43.439Z] Event: message 4
[2022-07-26T22:54:43.437Z] Event: message 3
[2022-07-26T22:54:43.441Z] Executed 'EventHubTrigger1' (Succeeded, Id=aec42a41-8093-4f61-b586-f03aec0fb26b, Duration=8ms)
[2022-07-26T22:54:43.441Z] EnqueuedTimeUtc=7/26/2022 10:54:26 PM
[2022-07-26T22:54:43.441Z] Executed 'EventHubTrigger1' (Succeeded, Id=6724dd37-3c3f-4676-bffb-ebb94888506b, Duration=18ms)
[2022-07-26T22:54:43.443Z] SequenceNumber=25
[2022-07-26T22:54:43.445Z] Offset=3136
[2022-07-26T22:54:43.442Z] EnqueuedTimeUtc=7/26/2022 10:54:20 PM
[2022-07-26T22:54:43.445Z] Executed 'EventHubTrigger1' (Succeeded, Id=b36aaf91-f23a-484e-abfb-025540e43b3c, Duration=8ms)
[2022-07-26T22:54:43.446Z] SequenceNumber=24
[2022-07-26T22:54:43.447Z] Offset=3024
[2022-07-26T22:54:43.448Z] Executed 'EventHubTrigger1' (Succeeded, Id=9064dbdc-7bee-4353-9b98-253fa0820f2b, Duration=13ms)
[2022-07-26T22:55:00.006Z] Executing 'QueueMessageProducer' (Reason='Timer fired at 2022-07-26T15:55:00.0033654-07:00', Id=e797f941-2472-428f-bab7-aca43db33996)
[2022-07-26T22:55:00.008Z] C# Timer trigger function executed at: 7/26/2022 10:55:00 PM
[2022-07-26T22:55:01.051Z] Executed 'QueueMessageProducer' (Succeeded, Id=e797f941-2472-428f-bab7-aca43db33996, Duration=1047ms)
[2022-07-26T22:55:01.090Z] Executing 'QueueTrigger' (Reason='(null)', Id=a6057d52-e033-4ce1-8435-71321a10462f)
[2022-07-26T22:55:01.092Z] Trigger Details: MessageId: 66acd633304947c1937ce9ec04c28990, SequenceNumber: 7545, DeliveryCount: 1, EnqueuedTimeUtc: 2022-07-26T22:55:02.0020000Z, LockedUntilUtc: 2022-07-26T22:55:32.0180000Z, SessionId: (null)
[2022-07-26T22:55:01.092Z] C# Service bus queue trigger function processed message: Message from QueueMessageProducer 7/26/2022 10:55:00 PM
[2022-07-26T22:55:01.094Z] Executed 'QueueTrigger' (Succeeded, Id=a6057d52-e033-4ce1-8435-71321a10462f, Duration=9ms)

Known workarounds

Upgrade to latest version (v5.x) of the extension

Extension Version

I have verified this behaviour with the latest version of the track 1 extension: Microsoft.Azure.WebJobs.Extensions.EventHubs v4.3.1.

I verified that this issue has been fixed in the latest version of the track 2 extension (v5.x)