beemines opened a new issue, #16455:
URL: https://github.com/apache/dubbo/issues/16455

   ### Pre-check
   
   - [x] All content is in English.
   - [x] I searched existing issues and pull requests for ActiveLimitFilter, 
ExecuteLimitFilter, active count, and limit-exception cleanup.
   
   ### Apache Dubbo Component
   
   Java SDK (apache/dubbo), dubbo-rpc-api filters and the dubbo-cluster filter 
chain.
   
   ### Dubbo Version
   
   3.3.7-SNAPSHOT, branch `3.3` at `dab47b7843`; Windows, OpenJDK 17.0.17, 
Maven 3.9.4.
   
   ### Steps to reproduce this issue
   
   Both concurrency filters skip `RpcStatus.endCount()` whenever their error 
listener receives a `RpcException` with `LIMIT_EXCEEDED_EXCEPTION`. This 
correctly skips cleanup when the filter itself rejects admission, but also 
skips it when admission succeeded and a downstream invoker throws that 
exception (or its response future completes exceptionally with it).
   
   A minimal synchronous reproduction in a test in `dubbo-cluster` (JUnit 5 / 
Mockito; ordinary imports omitted):
   
   ```java
   URL url = 
URL.valueOf("test://localhost:12345/limit-repro?actives=1&timeout=1");
   Invoker<Object> target = mock(Invoker.class);
   when(target.getUrl()).thenReturn(url);
   when(target.getInterface()).thenReturn(Object.class);
   when(target.invoke(any())).thenThrow(
           new RpcException(RpcException.LIMIT_EXCEEDED_EXCEPTION, "downstream 
rejected"));
   
   Filter filter = new ActiveLimitFilter();
   Invoker<Object> chain = new FilterChainBuilder.CallbackRegistrationInvoker<>(
           new FilterChainBuilder.CopyOfFilterChainNode<>(target, target, 
filter),
           Collections.singletonList(filter));
   RpcInvocation invocation = new RpcInvocation();
   invocation.setMethodName("invoke");
   
   assertThrows(RpcException.class, () -> chain.invoke(invocation));
   assertEquals(0, RpcStatus.getStatus(url, "invoke").getActive()); // actual: 1
   ```
   
   Replace `actives=1` with `executes=1` and use `ExecuteLimitFilter` to 
reproduce the provider-side case.
   
   For the asynchronous case, return `new AsyncRpcResult(pending, invocation)` 
from the target and complete `pending` exceptionally with the same limit 
exception after calling the chain. The active count also remains 1.
   
   ### What you expected to happen
   
   A call that acquired a concurrency slot must release it on downstream 
failure and record the failure. A local admission rejection must not release 
another in-flight call's slot.
   
   With a limit of 1, the leaked count causes later active-limit calls to time 
out or execute-limit calls to be rejected even though the failed call is no 
longer running.
   
   ### Verification
   
   I added eight parameterized regression cases through the production 
`CopyOfFilterChainNode` / `CallbackRegistrationInvoker` lifecycle. Before the 
fix, all four downstream-failure cases fail with `expected: <0> but was: <1>`; 
the four local-rejection / invocation-reuse controls pass. There are 0 test 
errors.
   
   The fix will track whether this filter acquired a slot for the current 
invocation attempt, resetting that state on each entry so sequential Invocation 
reuse does not carry stale admission state.
   
   This concerns exceptions delivered through `onError`, not ordinary business 
exceptions carried inside an otherwise successfully completed `AppResponse`. No 
registry, network service, or load generator is needed for the reproduction.
   
   AI assistance was used for source inspection, implementation, and regression 
tests. The failures above were reproduced locally, and I will submit the fix 
with the complete tests.
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to