@@ -70,54 +70,38 @@ public async Task<IList<TaskMessage>> FetchNewMessagesAsync(
7070 . OrderBy ( w => w . AvailableAt )
7171 . ThenBy ( w => w . SequenceNumber )
7272 . AsNoTracking ( )
73- . ToArrayAsync ( cancellationToken ) ;
74-
75- var messagesToDiscard = newDbMessages
76- . Where ( m => m . ExecutionId is not null && m . ExecutionId != Instance . LastExecutionId )
77- . ToArray ( ) ;
78-
79- if ( messagesToDiscard . Length > 0 )
80- {
81- foreach ( var message in messagesToDiscard )
82- {
83- dbContext . OrchestrationMessages . Attach ( message ) ;
84- dbContext . OrchestrationMessages . Remove ( message ) ;
85- }
86-
87- newDbMessages = newDbMessages
88- . Except ( messagesToDiscard )
89- . ToArray ( ) ;
90- }
73+ . ToListAsync ( cancellationToken ) ;
9174
9275 var deserializedMessages = newDbMessages
9376 . Select ( w => _options . DataConverter . Deserialize < TaskMessage > ( w . Message ) )
9477 . ToList ( ) ;
9578
96- if ( RuntimeState . ExecutionStartedEvent is not null )
79+ if ( RuntimeState . ExecutionStartedEvent is not null
80+ && RuntimeState . OrchestrationStatus is OrchestrationStatus . Completed
81+ && deserializedMessages . Any ( m => m . Event . EventType == EventType . EventRaised ) )
9782 {
98- if ( RuntimeState . OrchestrationStatus is OrchestrationStatus . Completed
99- && deserializedMessages . Any ( m => m . Event . EventType == EventType . EventRaised ) )
100- {
101- // Reopen completed orchestrations after receiving an event raised
102- RuntimeState = new OrchestrationRuntimeState (
103- RuntimeState . Events . Reopen ( _options . DataConverter )
104- ) ;
105- }
83+ // Reopen completed orchestrations after receiving an event raised
84+ RuntimeState = new OrchestrationRuntimeState (
85+ RuntimeState . Events . Reopen ( _options . DataConverter )
86+ ) ;
87+ }
88+
89+ var isRunning = RuntimeState . ExecutionStartedEvent is null
90+ || RuntimeState . OrchestrationStatus is OrchestrationStatus . Running
91+ or OrchestrationStatus . Suspended
92+ or OrchestrationStatus . Pending ;
10693
107- var isRunning = RuntimeState . OrchestrationStatus is OrchestrationStatus . Running
108- or OrchestrationStatus . Suspended
109- or OrchestrationStatus . Pending ;
94+ for ( var i = newDbMessages . Count - 1 ; i >= 0 ; i -- )
95+ {
96+ var dbMessage = newDbMessages [ i ] ;
97+ var deserializedMessage = deserializedMessages [ i ] ;
11098
111- if ( ! isRunning )
99+ if ( ShouldDropNewMessage ( isRunning , dbMessage , deserializedMessage ) )
112100 {
113- // Discard all messages if not running
114- foreach ( var message in newDbMessages )
115- {
116- dbContext . OrchestrationMessages . Attach ( message ) ;
117- dbContext . OrchestrationMessages . Remove ( message ) ;
118- }
119- newDbMessages = [ ] ;
120- deserializedMessages = [ ] ;
101+ dbContext . OrchestrationMessages . Attach ( dbMessage ) ;
102+ dbContext . OrchestrationMessages . Remove ( dbMessage ) ;
103+ newDbMessages . RemoveAt ( i ) ;
104+ deserializedMessages . RemoveAt ( i ) ;
121105 }
122106 }
123107
@@ -126,6 +110,22 @@ or OrchestrationStatus.Suspended
126110 return deserializedMessages ;
127111 }
128112
113+ private bool ShouldDropNewMessage (
114+ bool isRunning ,
115+ OrchestrationMessage dbMessage ,
116+ TaskMessage taskMessage )
117+ {
118+ // Drop messages to previous executions
119+ if ( dbMessage . ExecutionId is not null && dbMessage . ExecutionId != Instance . LastExecutionId )
120+ return true ;
121+
122+ // When not running, drop anything that is not execution rewound
123+ if ( ! isRunning && taskMessage . Event . EventType != EventType . ExecutionRewound )
124+ return true ;
125+
126+ return false ;
127+ }
128+
129129 public void ClearMessages ( )
130130 {
131131 Messages . Clear ( ) ;
0 commit comments