Skip to content

Commit 7ba7ee6

Browse files
committed
fix(worker-ops): prevent scheduler stall on invalid request recovery
1 parent 6000be9 commit 7ba7ee6

1 file changed

Lines changed: 18 additions & 9 deletions

File tree

cadence/contracts/FlowYieldVaultsEVMWorkerOps.cdc

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,6 @@ access(all) contract FlowYieldVaultsEVMWorkerOps {
491491
let manager = FlowYieldVaultsEVMWorkerOps._getManagerFromStorage()!
492492
let worker = self.workerCap.borrow()!
493493

494-
// Always run failed-worker recovery before capacity checks.
495-
// This prevents stale in-flight entries from blocking scheduler progress.
496-
self._checkForFailedWorkerRequests(manager: manager, worker: worker)
497-
498494
var message = ""
499495
var nextRunCapacity: UInt8 = 0
500496
var pendingCount: Int? = nil
@@ -508,7 +504,15 @@ access(all) contract FlowYieldVaultsEVMWorkerOps {
508504
// Calculate available capacity safely.
509505
// Guard against underflow if maxProcessingRequests is reduced while requests are in flight.
510506
let maxProcessingRequests = FlowYieldVaultsEVMWorkerOps.maxProcessingRequests
511-
let currentInFlight = FlowYieldVaultsEVMWorkerOps.scheduledRequests.length
507+
var currentInFlight = FlowYieldVaultsEVMWorkerOps.scheduledRequests.length
508+
509+
// If capacity is saturated, run failed-worker recovery first to clear stale entries
510+
// that would otherwise block pending-request processing.
511+
if currentInFlight >= Int(maxProcessingRequests) {
512+
self._checkForFailedWorkerRequests(manager: manager, worker: worker)
513+
currentInFlight = FlowYieldVaultsEVMWorkerOps.scheduledRequests.length
514+
}
515+
512516
// capacityLimit:
513517
// Remaining worker slots available right now, based on in-flight workers.
514518
// capacityLimit = max(0, maxProcessingRequests - currentInFlight)
@@ -574,10 +578,12 @@ access(all) contract FlowYieldVaultsEVMWorkerOps {
574578

575579
/// @notice Main scheduler logic
576580
/// @dev Flow:
577-
/// 1. If fetchCount > 0, fetch pending requests from EVM
578-
/// 2. Preprocess requests to drop invalid requests
579-
/// 3. Start processing requests (PENDING -> PROCESSING)
580-
/// 4. Schedule WorkerHandlers and assign request ids to them
581+
/// 1. Check for failed worker requests
582+
/// - If a failure is identified, mark the request as failed and remove it from scheduledRequests
583+
/// 2. If fetchCount > 0, fetch pending requests from EVM
584+
/// 3. Preprocess requests to drop invalid requests
585+
/// 4. Start processing requests (PENDING -> PROCESSING)
586+
/// 5. Schedule WorkerHandlers and assign request ids to them
581587
/// @param manager The scheduler manager
582588
/// @param worker The worker resource
583589
/// @param fetchCount Number of pending requests to fetch in this run
@@ -587,6 +593,9 @@ access(all) contract FlowYieldVaultsEVMWorkerOps {
587593
worker: &FlowYieldVaultsEVM.Worker,
588594
fetchCount: Int,
589595
): String? {
596+
// Check for failed worker requests
597+
self._checkForFailedWorkerRequests(manager: manager, worker: worker)
598+
590599
// Fetch pending requests from EVM
591600
if fetchCount > 0 {
592601
if let pendingRequests = worker.getPendingRequestsFromEVM(

0 commit comments

Comments
 (0)