@@ -116,6 +116,9 @@ public async Task<IReadOnlyCollection<DurableAction>> ClaimPendingAsync(
116116 if ( IsSqlServer ( ) )
117117 return await ClaimSqlServerAsync ( lane , batchSize , lockExpiration , now , cancellationToken ) ;
118118
119+ if ( _dbContext . Database . IsRelational ( ) )
120+ return await ClaimRelationalAsync ( lane , batchSize , lockExpiration , now , cancellationToken ) ;
121+
119122 return await ClaimTrackedAsync ( lane , batchSize , lockExpiration , now , cancellationToken ) ;
120123 }
121124
@@ -188,6 +191,58 @@ private async Task<IReadOnlyCollection<DurableAction>> ClaimTrackedAsync(
188191 return candidates . ToArray ( ) ;
189192 }
190193
194+ private async Task < IReadOnlyCollection < DurableAction > > ClaimRelationalAsync (
195+ string lane ,
196+ int batchSize ,
197+ DateTimeOffset lockExpiration ,
198+ DateTimeOffset now ,
199+ CancellationToken cancellationToken )
200+ {
201+ var normalizedLane = NormalizeLane ( lane ) ;
202+ var candidates = await Actions
203+ . AsNoTracking ( )
204+ . Where ( x =>
205+ x . Lane == normalizedLane &&
206+ ( x . Status == DurableActionStatus . Pending || x . Status == DurableActionStatus . Locked ) )
207+ . Select ( x => new
208+ {
209+ x . Id ,
210+ x . Status ,
211+ x . CreatedOnUtc ,
212+ x . LockedOnUtc ,
213+ x . NextAttemptOnUtc
214+ } )
215+ . ToListAsync ( cancellationToken ) ;
216+
217+ var candidateIds = candidates
218+ . Where ( x =>
219+ x . Status == DurableActionStatus . Pending && ( x . NextAttemptOnUtc == null || x . NextAttemptOnUtc <= now ) ||
220+ x . Status == DurableActionStatus . Locked && x . LockedOnUtc <= lockExpiration )
221+ . OrderBy ( x => x . NextAttemptOnUtc ?? x . CreatedOnUtc )
222+ . ThenBy ( x => x . CreatedOnUtc )
223+ . Select ( x => x . Id )
224+ . Take ( batchSize )
225+ . ToArray ( ) ;
226+
227+ if ( candidateIds . Length == 0 )
228+ return Array . Empty < DurableAction > ( ) ;
229+
230+ var claimed = new List < DurableAction > ( candidateIds . Length ) ;
231+ foreach ( var id in candidateIds )
232+ {
233+ var locked = await LockRelationalAsync ( id , lockExpiration , now , cancellationToken ) ;
234+ if ( locked == 0 )
235+ continue ;
236+
237+ var action = await Actions
238+ . AsNoTracking ( )
239+ . SingleAsync ( x => x . Id == id , cancellationToken ) ;
240+ claimed . Add ( action ) ;
241+ }
242+
243+ return claimed ;
244+ }
245+
191246 public async Task MarkCompletedAsync ( Guid id , DateTimeOffset completedOnUtc , CancellationToken cancellationToken = default )
192247 {
193248 if ( IsSqlServer ( ) )
0 commit comments