apache / apache/shenyu

[BUG] Websocket MYSELF/REFRESH uses partial "self" refresh — ghost cache entries survive reconnect (plugin, selector, rule, auth caches)

Open
#6,731 1 comment 0 reactions 0 assignees View on GitHub
data-sync: websocket priority: medium type: bug
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.