-
Notifications
You must be signed in to change notification settings - Fork 92
Bound Gateway cache lifetime and capacity #516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
GOLDKUN
wants to merge
2
commits into
chaitin:main
Choose a base branch
from
GOLDKUN:perf/bound-gateway-cache-lifetime
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package protocol | ||
|
|
||
| import ( | ||
| "net/http" | ||
| "testing" | ||
| "time" | ||
| ) | ||
|
|
||
| func TestGatewayCacheEntriesExpireAndInvalidateTogether(t *testing.T) { | ||
| gateway := &Gateway{ | ||
| mcpToolsCache: map[string][]map[string]any{"expired": {{"name": "tool"}}}, | ||
| connectCache: map[string]http.Handler{"expired": http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})}, | ||
| mcpCacheAt: map[string]time.Time{"expired": time.Now().Add(-gatewayCacheTTL)}, | ||
| connectCacheAt: map[string]time.Time{"expired": time.Now().Add(-gatewayCacheTTL)}, | ||
| } | ||
| gateway.mu.Lock() | ||
| gateway.evictExpiredCachesLocked(time.Now()) | ||
| gateway.mu.Unlock() | ||
| if len(gateway.mcpToolsCache) != 0 || len(gateway.connectCache) != 0 { | ||
| t.Fatalf("expired gateway cache entries remain: mcp=%d connect=%d", len(gateway.mcpToolsCache), len(gateway.connectCache)) | ||
| } | ||
| } | ||
|
|
||
| func TestGatewayInstanceInvalidationClearsSchemaCaches(t *testing.T) { | ||
| gateway := &Gateway{ | ||
| mcpToolsCache: map[string][]map[string]any{"cached": {{"name": "tool"}}}, | ||
| connectCache: map[string]http.Handler{"cached": http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})}, | ||
| mcpCacheAt: map[string]time.Time{"cached": time.Now()}, | ||
| connectCacheAt: map[string]time.Time{"cached": time.Now()}, | ||
| } | ||
| gateway.InvalidateInstance("missing-instance") | ||
| if len(gateway.mcpToolsCache) != 0 || len(gateway.connectCache) != 0 { | ||
| t.Fatal("instance invalidation left stale schema caches") | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
每次缓存访问都在全局锁下全量扫描缓存做过期淘汰,热路径由 O(1) 退化为 O(n)
mcpTools(887 行)与 connectHandler(1268 行)在每次调用、持有全局 g.mu 时都执行 evictExpiredCachesLocked,该函数会完整遍历 mcpCacheAt 与 connectCacheAt 两张 map(每张最多 gatewayCacheMaxEntries=1024 项)。即使缓存全部命中、没有任何过期项,每次请求也要做最多约 2048 次时间比较并串行化在全局互斥锁内。改动前热路径只是 O(1) 的 map 读取;改动后所有网关请求在全局锁下承担 O(cache) 的清扫成本,高 QPS 下会放大锁竞争与请求延迟,且该成本与缓存命中与否无关。
Problem code:
Recommendation:
将过期淘汰从每次访问的全量 O(n) 扫描改为摊销/懒淘汰:读取时只检查目标 cacheKey 自身的过期时间,命中即返回;仅在写入新条目或周期性(每 N 次访问/后台定时器)时才做全量清扫。若保留全量扫描,至少将其移出读路径。