How to Proactively Dequeue Failing PRs

Learn how proactive dequeue identifies and removes failing PRs from the middle of the parallel mode queue without waiting for them to reach the top.

In parallel mode, each draft PR includes the cumulative commits of all preceding queued PRs plus its own batch. When a draft PR's CI fails, the failure is normally only acted upon when that draft PR reaches the top of the queue. This means a failing PR in the middle of the queue can delay progress until all preceding PRs are merged first.

Proactive dequeue solves this by using a simple heuristic: if all of a draft PR's dependencies have no failing CI but the draft PR itself has failed CI, then the batch of PRs unique to that draft PR likely introduced the failure. Aviator can proactively dequeue those PRs without waiting for them to reach the top.

Configuration

Both properties live under merge_rules.merge_mode.parallel_mode in your Aviator configuration file.

use_proactive_dequeue

Enables proactive dequeue for your repository. When enabled, Aviator scans non-top draft PRs during each queue processing cycle and dequeues any that meet the heuristic criteria.

Property
Value

Type

boolean

Default

false

proactive_dequeue_delay_seconds

Number of seconds to wait after a draft PR CI failure is detected before proactively dequeuing. This delay helps avoid false positives from transient or flaky test failures. Only applicable when use_proactive_dequeue is true. A value of 0 means Aviator will dequeue as soon as the heuristic conditions are met.

Property
Value

Type

integer

Default

0

Example

version: 1.0.0
merge_rules:
  labels:
    trigger: "mergequeue"
  merge_mode:
    type: "parallel"
    parallel_mode:
      max_parallel_builds: 10
      batch_size: 1
      use_proactive_dequeue: true
      proactive_dequeue_delay_seconds: 300

How it works

Consider a queue with three draft PRs:

Draft PR #2 includes commits from PR A and PR B (carried forward from Draft PR #1) plus PR C and PR D (its own batch). Since Draft PR #1 is pending with only A and B, but Draft PR #2 fails after adding C and D, the failure is likely caused by PR C or PR D.

With proactive dequeue enabled, Aviator will:

  1. Detect that Draft PR #2 has at least one failing CI check.

  2. Verify that Draft PR #1 (the dependency) has no failing CI.

  3. Wait for the configured delay if proactive_dequeue_delay_seconds is set.

  4. Dequeue PR C and PR D from the queue.

  5. Resync Draft PR #3 to remove the dequeued commits and retrigger CI.

A comment is posted on the affected PRs explaining that they were proactively dequeued and why.

With batching

When batch_size is greater than 1, the proactive dequeue identifies the failing batch but cannot pinpoint the exact PR within the batch. In this case, the PRs in the batch are requeued for bisection to narrow down the culprit, rather than being immediately blocked.

With affected targets

When use_affected_targets is enabled, draft PRs may have multiple dependencies rather than a single linear predecessor. Aviator checks all dependent draft PRs in the dependency graph. Every dependency must have no failing CI before the proactive dequeue heuristic fires.

When proactive dequeue does not fire

The heuristic is intentionally conservative. No action is taken when:

  • Any dependency is also failing. The failure could be cascading from an upstream batch. Aviator lets normal top-of-queue processing handle it.

  • The draft PR is a bisected batch. Bisection has its own processing path.

  • The draft PR is at the top of the queue. Normal queue processing already handles top-of-queue failures.

  • The configured delay has not elapsed. Aviator re-checks on the next processing cycle.

Considerations

Since this is a preemptive dequeue behavior, there is a scenario where an incorrect PR may be dequeued. Take for example the above example:

In this case, it's possible that the real failure was in PR A, and eventually Draft PR #1 may also fail. This can happen if the CI runs in a non-deterministic way. Typically, CI of Draft PR #1 should be ahead of CI of Draft PR #2, but this may not always be the case.

Recommendations

  • Start with a delay. Setting proactive_dequeue_delay_seconds to 300-600 seconds gives transient failures time to resolve before Aviator acts. You can reduce it once you are confident in the behavior for your repository.

  • Works best with batch_size: 1. When each draft PR contains a single queued PR, the heuristic can directly identify the failing PR. With larger batch sizes, the failing batch is requeued for bisection, which still saves time but requires additional CI cycles.

  • Complements optimistic validation. Proactive dequeue identifies failing PRs in the middle of the queue, while use_optimistic_validation recovers from flaky failures at the top. Both can be enabled simultaneously without conflict.

Last updated

Was this helpful?