Skip to content

[BUG] Dubbo inflight invoker wrapper breaks provider identity during retry reselection #8132

Closed

Description

@Aias00

Environment

Master aab453f06dbd135da9b329ee153758ceac0e1834 (2.7.3-SNAPSHOT), Apache Dubbo gray routing using leastActive; project dependency Dubbo 3.2.14.

Problem

The new counting wrapper compares equal to its delegate in one direction only. Dubbo's retry reselection checks original directory invokers against its already-tried list, which can contain wrappers. This comparison fails and allows an already-tried provider back into the retry candidates, even when another provider is available.

Reproduction and observed result

An isolated probe exercised Dubbo 3.2.14's actual AbstractClusterInvoker.select implementation:

  1. Provide two available directory invokers A and B.
  2. Put an InflightInvoker wrapping A in the already-tried list, representing a previous invocation attempt.
  3. Use a deterministic load balancer returning a fresh counting wrapper around the first admitted candidate. This exposes whether reselection excludes A.
  4. Invoke the real cluster selector with both providers available.

Observed:

wrapper.equals(original) = true
original.equals(wrapper) = false
alreadyTried.contains(original) = false
selectedFailedProviderAgain = true

The load balancer is deterministic in this probe so the incorrect candidate admission is reproducible. No network RPC was executed.

Root cause

InflightInvoker.equals delegates equality for wrapper-to-original comparisons, but cannot change the original invoker's equality implementation. In AbstractClusterInvoker.reselect, the candidate being tested is an original directory invoker, so selected.contains(candidate) uses candidate.equals(wrapper) and does not exclude it.

ApacheDubboGrayLoadBalance introduces the wrapper on the least-active gray path. The current identity test covers wrapper-to-original equality and originalInvokers.contains(wrapper), which exercises the opposite comparison direction from retry reselection.

Expected behavior / acceptance

  • Preserve canonical provider identity throughout Dubbo directory, selection, already-tried and invalidation bookkeeping. A one-sided equality override is insufficient for arbitrary invokers.
  • With A already tried and B available, reselection excludes A and chooses B.
  • Test against the actual cluster selection/reselection implementation, not only direct wrapper equality assertions.
  • Preserve exactly-once inflight accounting for repeated invocation, completion, exceptions and cancellation where supported.

Validation boundary

Behavior reproduced with the project's actual Dubbo cluster implementation and counting wrapper, mocked directory invokers and a deterministic selector. This is not a live Dubbo failover integration test.

Metadata

Metadata

Assignees

Labels

type: bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions