@@ -147,63 +147,67 @@ public Task ProcessErrorAsync(EventProcessorHostPartition context, Exception err
147147 return Task . CompletedTask ;
148148 }
149149
150- public async Task ProcessEventsAsync ( EventProcessorHostPartition context , IEnumerable < EventData > messages )
150+ public async Task ProcessEventsAsync ( EventProcessorHostPartition context , IEnumerable < EventData > messages , CancellationToken processingCancellationToken )
151151 {
152- var events = messages . ToArray ( ) ;
153- EventData eventToCheckpoint = null ;
154-
155- var triggerInput = new EventHubTriggerInput
152+ using ( CancellationTokenSource linkedCts =
153+ CancellationTokenSource . CreateLinkedTokenSource ( _cts . Token , processingCancellationToken ) )
156154 {
157- Events = events ,
158- ProcessorPartition = context
159- } ;
155+ var events = messages . ToArray ( ) ;
156+ EventData eventToCheckpoint = null ;
160157
161- if ( _singleDispatch )
162- {
163- // Single dispatch
164- int eventCount = triggerInput . Events . Length ;
158+ var triggerInput = new EventHubTriggerInput
159+ {
160+ Events = events ,
161+ ProcessorPartition = context
162+ } ;
165163
166- for ( int i = 0 ; i < eventCount ; i ++ )
164+ if ( _singleDispatch )
167165 {
168- if ( _cts . IsCancellationRequested )
166+ // Single dispatch
167+ int eventCount = triggerInput . Events . Length ;
168+
169+ for ( int i = 0 ; i < eventCount ; i ++ )
169170 {
170- break ;
171+ if ( linkedCts . Token . IsCancellationRequested )
172+ {
173+ break ;
174+ }
175+
176+ EventHubTriggerInput eventHubTriggerInput = triggerInput . GetSingleEventTriggerInput ( i ) ;
177+ TriggeredFunctionData input = new TriggeredFunctionData
178+ {
179+ TriggerValue = eventHubTriggerInput ,
180+ TriggerDetails = eventHubTriggerInput . GetTriggerDetails ( context )
181+ } ;
182+
183+ await _executor . TryExecuteAsync ( input , linkedCts . Token ) . ConfigureAwait ( false ) ;
184+ eventToCheckpoint = events [ i ] ;
171185 }
172-
173- EventHubTriggerInput eventHubTriggerInput = triggerInput . GetSingleEventTriggerInput ( i ) ;
186+ }
187+ else
188+ {
189+ // Batch dispatch
174190 TriggeredFunctionData input = new TriggeredFunctionData
175191 {
176- TriggerValue = eventHubTriggerInput ,
177- TriggerDetails = eventHubTriggerInput . GetTriggerDetails ( context )
192+ TriggerValue = triggerInput ,
193+ TriggerDetails = triggerInput . GetTriggerDetails ( context )
178194 } ;
179195
180- await _executor . TryExecuteAsync ( input , _cts . Token ) . ConfigureAwait ( false ) ;
181- eventToCheckpoint = events [ i ] ;
196+ await _executor . TryExecuteAsync ( input , linkedCts . Token ) . ConfigureAwait ( false ) ;
197+ eventToCheckpoint = events . LastOrDefault ( ) ;
182198 }
183- }
184- else
185- {
186- // Batch dispatch
187- TriggeredFunctionData input = new TriggeredFunctionData
188- {
189- TriggerValue = triggerInput ,
190- TriggerDetails = triggerInput . GetTriggerDetails ( context )
191- } ;
192199
193- await _executor . TryExecuteAsync ( input , _cts . Token ) . ConfigureAwait ( false ) ;
194- eventToCheckpoint = events . LastOrDefault ( ) ;
195- }
196-
197- // Checkpoint if we processed any events.
198- // Don't checkpoint if no events. This can reset the sequence counter to 0.
199- // Note: we intentionally checkpoint the batch regardless of function
200- // success/failure. EventHub doesn't support any sort "poison event" model,
201- // so that is the responsibility of the user's function currently. E.g.
202- // the function should have try/catch handling around all event processing
203- // code, and capture/log/persist failed events, since they won't be retried.
204- if ( eventToCheckpoint != null )
205- {
206- await CheckpointAsync ( eventToCheckpoint , context ) . ConfigureAwait ( false ) ;
200+ // Checkpoint if we processed any events.
201+ // Don't checkpoint if no events. This can reset the sequence counter to 0.
202+ // Note: we intentionally checkpoint the batch regardless of function
203+ // success/failure. EventHub doesn't support any sort "poison event" model,
204+ // so that is the responsibility of the user's function currently. E.g.
205+ // the function should have try/catch handling around all event processing
206+ // code, and capture/log/persist failed events, since they won't be retried.
207+ if ( eventToCheckpoint != null )
208+ {
209+ await CheckpointAsync ( eventToCheckpoint , context ) . ConfigureAwait ( false ) ;
210+ }
207211 }
208212 }
209213
0 commit comments