[BUG] Websocket MYSELF/REFRESH uses partial "self" refresh — ghost cache entries survive reconnect (plugin, selector, rule, auth caches)
- Dominant language
- Java
- Stars
- 8.8k
- Forks
- 3.1k
- Avg merge
- 7d 1h
- Merged PRs (30d)
- 85
Description
- Severity: Medium-High
- Location:
`shenyu-sync-data-center/shenyu-sync-data-websocket/src/main/java/org/apache/shenyu/plugin/sync/data/websocket/handler/AbstractDataHandler.java:71-73` (`MYSELF`/`REFRESH` → `doRefresh`); `PluginDataHandler.java:43-46`, `SelectorDataHandler.java:43-46`, `RuleDataHandler.java:42-45` (`doRefresh` → `refreshXxxDataSelf`); `shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/CommonPluginDataSubscriber.java:127-133` (`refreshPluginDataSelf`), `:155-160` (`refreshSelectorDataSelf` — does NOT clean MatchDataCache), `:182-187` (`refreshRuleDataSelf` — does NOT clean MatchDataCache); `shenyu-plugin/shenyu-plugin-security/shenyu-plugin-sign/src/main/java/org/apache/shenyu/plugin/sign/subscriber/SignAuthDataSubscriber.java` (no `refresh()` override → default no-op → `SignAuthDataCache` never cleared)
-
Description:
On reconnect, the gateway sends `MYSELF`; admin replies with the full current snapshot. `AbstractDataHandler.handle` routes `MYSELF` to `doRefresh`, which calls `refreshXxxDataSelf(dataList)`. `refreshPluginDataSelf` only calls `cleanPluginDataSelf` (removes only items *present in the payload*), not `refreshPluginDataAll()` (full clear). `refreshSelectorDataSelf`/`refreshRuleDataSelf` likewise only do partial BaseDataCache cleaning and do **not** clean `MatchDataCache` (compare `refreshSelectorDataAll`/`refreshRuleDataAll` at lines 148-152/175-179 which clean both). For auth, `SignAuthDataSubscriber` has no `refresh()` override (the interface default is a no-op), so `SignAuthDataCache` is never cleared. Contrast: HTTP long-polling transport (`SelectorDataRefresh.java`) correctly calls `refreshSelectorDataAll()` (full clear) — an inconsistency between sync transports.
-
Impact:
After any gateway reconnect following an admin-side delete, deleted selectors/rules/auth keys persist in gateway caches until process restart → traffic routed to deleted selectors/rules, stale match-cache entries, stale auth keys retained.
-
Suggested fix:
Route `MYSELF` to a full-replace path that calls `refreshXxxDataAll()` (clear BaseDataCache + MatchDataCache) before re-subscribing. Add `refresh()` overrides to `SignAuthDataSubscriber` that clear `SignAuthDataCache`.
-
Confidence: High (verified: `refreshSelectorDataSelf` does not clean MatchDataCache; `SignAuthDataSubscriber` has no refresh override)
- Related existing: #6569 is the HTTP long-polling path; #6479 is discovery-upstream specific; PERF-14 is a different class.
---
_Identified during the 2026-08-02 deep re-scan; full list in [`docs/scan2-2026-08-02/06-medium-tiers.md`](docs/scan2-2026-08-02/06-medium-tiers.md)._
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at AbstractDataHandler.java:71-73 and trace MYSELF/REFRESH through PluginDataHandler.java, SelectorDataHandler.java, RuleDataHandler.java, and CommonPluginDataSubscriber.java. Compare the websocket path with SelectorDataRefresh.java and inspect SignAuthDataSubscriber.java; done means reconnect refreshes fully remove stale base, match, and authentication cache entries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100