[BUG] ZooKeeper registry keeps stale instances when the last child is removed
- 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-registry
### What happened
`ZookeeperInstanceRegisterRepository.selectInstances()` maintains `watcherInstanceRegisterMap` from ZooKeeper child changes. The watcher callback only updates the cache when the new child list is not empty:
```java
List childrenList = StringUtils.isNotBlank(path) ? client.subscribeChildrenChanges(path, this)
: Collections.emptyList();
if (!childrenList.isEmpty()) {
watcherInstanceRegisterMap.put(selectKey, getInstanceRegisterFun.apply(childrenList));
}
```
When the last instance child under a watched service is removed, `childrenList` becomes empty. Because the callback skips the `put`, the old non-empty `watcherInstanceRegisterMap` entry remains.
Later `selectInstances(selectKey)` returns the stale cached instances immediately:
```java
if (watcherInstanceRegisterMap.containsKey(selectKey)) {
return watcherInstanceRegisterMap.get(selectKey);
}
```
So a service can continue to appear as having upstream instances even after all ZooKeeper instance nodes have been deleted.
### What you expected to happen
When ZooKeeper reports an empty child list for a watched service, ShenYu should update the cache to an empty list or remove the cache entry. Subsequent `selectInstances(selectKey)` calls should reflect that no instances remain.
### How to reproduce
1. Use ZooKeeper discovery.
2. Register one instance for a service and call `selectInstances(serviceName)` so `watcherInstanceRegisterMap` is populated.
3. Remove the only child instance node for that service.
4. Let the watcher callback run with an empty `childrenList`.
5. Call `selectInstances(serviceName)` again.
6. The method returns the old cached instance because the cache was not cleared or replaced with an empty list.
### Debug logs
_No response_
### Environment
Current master branch.
### Are you willing to submit PR?
- [ ] Yes I am willing to submit a PR!
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with ZookeeperInstanceRegisterRepository.selectInstances() and the watcher callback that updates watcherInstanceRegisterMap. Reproduce the sequence with one ZooKeeper child, remove it, and call selectInstances() again; done means an empty child list no longer leaves stale instances in the cache.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- distributed-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100