[BUG] RPC client registration does not persist upstream status changes in selector handles
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
### Search before asking
- [x] I had searched in the [issues](https://github.com/apache/shenyu/issues) and found no similar issues.
### Apache ShenYu Component
shenyu-admin
### What happened
The Dubbo, gRPC, and Tars client registration services detect upstream status changes, but they do not apply those changes to the `existList` that is serialized back into the selector handle.
For example, `ShenyuClientRegisterGrpcServiceImpl.buildHandle(...)` does this:
```java
List existList = GsonUtils.getInstance().fromCurrentList(selectorDO.getHandle(), GrpcUpstream.class);
...
List diffStatusList = addList.stream().filter(upstream -> !upstream.isStatus()
|| existList.stream().anyMatch(e -> e.equals(upstream) && e.isStatus() != upstream.isStatus())).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(diffStatusList)) {
canAddList.addAll(diffStatusList);
}
...
return GsonUtils.getInstance().toJson(CollectionUtils.isEmpty(existList) ? canAddList : existList);
```
The same pattern exists in the Dubbo and Tars registration services.
The upstream `equals(...)` methods compare identity fields such as host/protocol/url/namespace, but they do not include `status`. Therefore a status-only change is detected in `diffStatusList`, but the matching object already in `existList` keeps its old status. Since the method serializes `existList` when it is not empty, the selector handle written back to DB still contains the stale status.
This affects status changes such as a single-node deleted/offline event where the new upstream is marked `status=false` before diffing.
### Expected behavior
When an existing upstream is re-registered with a different status, the matching item inside `existList` should be updated before the handle is serialized. The persisted selector handle should reflect the same status change that the registration flow detected.
### How to reproduce
1. Register a Dubbo, gRPC, or Tars upstream so the selector handle contains the upstream with `status=true`.
2. Send a registration event for the same upstream with `EventType.DELETED`, causing the newly built upstream to be marked `status=false`.
3. `diffStatusList` detects the changed status and adds it to `canAddList`.
4. Because `existList` is not updated, the method returns `GsonUtils.toJson(existList)` with the original `status=true` value.
5. The DB selector handle remains stale, so admin display/export/restart replay can use the old upstream status.
### Debug logs
_No response_
### Environment
Current `master` branch.
### Are you willing to submit a PR?
- [ ] Yes I am willing to submit a PR!
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with ShenyuClientRegisterGrpcServiceImpl.buildHandle(...) and trace the corresponding Dubbo and Tars registration-service implementations, focusing on how existList is compared and serialized. Reproduce a status-only re-registration for an existing upstream, then verify that the persisted selector handle reflects the changed status for all three protocols.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100