Skip to content

feat: 动态获取 Antigravity User-Agent 版本号#2535

Merged
luispater merged 1 commit intorouter-for-me:devfrom
rensumo:main
Apr 4, 2026
Merged

feat: 动态获取 Antigravity User-Agent 版本号#2535
luispater merged 1 commit intorouter-for-me:devfrom
rensumo:main

Conversation

@rensumo
Copy link
Copy Markdown
Contributor

@rensumo rensumo commented Apr 4, 2026

1.主要改动 (What)

  • 新增工具函数 (internal/misc/antigravity_version.go):
    • 实现了 AntigravityLatestVersion():通过 HTTP 请求访问 antigravity-auto-updater 接口。
    • 引入了 6 小时缓存机制,使用 sync.RWMutex 保证并发安全,避免频繁请求 API。
    • 提供了 降级方案 (Fallback):如果远程 API 请求失败或数据格式异常,将自动回退到默认版本 1.21.9
  • 更新执行器 (internal/runtime/executor/antigravity_executor.go):
    • 修改了 resolveUserAgent 函数,由原来的直接返回常量改为调用 misc.AntigravityUserAgent()
    • 将原有的 defaultAntigravityAgent 标记为仅作为 Fallback 使用。

2.测试验证 (Testing)

  • API 连通性测试:验证能够正确从远程接口解析出版本号。
  • 缓存逻辑测试:验证在 6 小时内多次调用时,不会触发重复的 HTTP 请求。
  • 错误处理测试:验证在断网或 API 返回 500 时,系统能正确回退到 1.21.9

Fetch the latest version from the antigravity auto-updater releases
endpoint and cache it for 6 hours. Falls back to 1.21.9 if the API
is unreachable or returns unexpected data.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a dynamic version fetching mechanism for the 'antigravity' service, replacing hardcoded User-Agent strings with a centralized utility in a new misc package. The implementation includes a caching layer with a 6-hour TTL and a fallback version. Feedback highlights several critical improvements: moving the network request outside of the write lock to avoid performance bottlenecks, implementing io.LimitReader to prevent potential memory exhaustion from large API responses, and reducing the cache duration for failed fetches to ensure quicker recovery from transient network issues. Additionally, it is recommended to remove the now-obsolete defaultAntigravityAgent constant.

Comment on lines +44 to +55
antigravityVersionMu.Lock()
defer antigravityVersionMu.Unlock()

// Double-check after acquiring write lock.
if cachedAntigravityVersion != "" && time.Now().Before(antigravityVersionExpiry) {
return cachedAntigravityVersion
}

version := fetchAntigravityLatestVersion()
cachedAntigravityVersion = version
antigravityVersionExpiry = time.Now().Add(antigravityVersionCacheTTL)
return version
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

在持有写锁 (antigravityVersionMu.Lock()) 的情况下执行网络请求 (fetchAntigravityLatestVersion()) 会导致严重的性能瓶颈。在高并发场景下,一旦缓存过期,所有调用此函数的 goroutine(包括仅需要读锁的请求)都会被阻塞,直到 HTTP 请求完成(最长可达 10 秒)。这可能导致请求堆积和资源耗尽。建议在锁外执行网络请求,或者使用 golang.org/x/sync/singleflight 来确保只有一个在途请求,避免阻塞其他读取操作。

Comment on lines +4 to +12
import (
"encoding/json"
"fmt"
"net/http"
"sync"
"time"

log "github.com/sirupsen/logrus"
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

建议引入 io 包,以便在解码 HTTP 响应时使用 io.LimitReader 限制读取大小,防止潜在的内存溢出风险。

Suggested change
import (
"encoding/json"
"fmt"
"net/http"
"sync"
"time"
log "github.com/sirupsen/logrus"
)
import (
"encoding/json"
"fmt"
"io"
"net/http"
"sync"
"time"
log "github.com/sirupsen/logrus"
)

Comment on lines +52 to +54
version := fetchAntigravityLatestVersion()
cachedAntigravityVersion = version
antigravityVersionExpiry = time.Now().Add(antigravityVersionCacheTTL)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

当获取版本失败并返回降级版本时,目前仍会将其缓存 6 小时 (antigravityVersionCacheTTL)。如果失败是由瞬时网络抖动引起的,系统将在很长一段时间内无法自动恢复。建议对获取失败的情况使用更短的缓存时间(例如 1-5 分钟),以便系统能更快地重试并恢复到最新版本。

}

var releases []antigravityRelease
if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

建议使用 io.LimitReader 限制读取的字节数。如果远程端点返回异常巨大的 Payload,可能会导致内存消耗过高甚至 OOM。增加此限制可以提高系统的健壮性。

Suggested change
if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
if err := json.NewDecoder(io.LimitReader(resp.Body, 64*1024)).Decode(&releases); err != nil {

antigravityClientID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com"
antigravityClientSecret = "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"
defaultAntigravityAgent = "antigravity/1.21.9 darwin/arm64"
defaultAntigravityAgent = "antigravity/1.21.9 darwin/arm64" // fallback only; overridden at runtime by misc.AntigravityUserAgent()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

常量 defaultAntigravityAgent 在当前代码中已不再被实际使用。resolveUserAgent 函数已改为调用 misc.AntigravityUserAgent(),而后者内部已经包含了降级逻辑。建议移除此常量以避免混淆并保持代码整洁。

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8d5e470e1f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +53 to +54
cachedAntigravityVersion = version
antigravityVersionExpiry = time.Now().Add(antigravityVersionCacheTTL)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep last cached version when refresh falls back

When the cache expires, any transient failure in fetchAntigravityLatestVersion() returns the fallback 1.21.9, and this code unconditionally stores that fallback and resets the 6-hour TTL. That discards a previously valid fetched version and can pin all requests to an older UA for hours after a brief updater outage, which risks avoidable request failures if upstream starts rejecting older versions. Only update the cache when the refresh succeeds, otherwise keep the last known good version.

Useful? React with 👍 / 👎.

return cachedAntigravityVersion
}

version := fetchAntigravityLatestVersion()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Move network fetch out of the version cache lock

AntigravityLatestVersion() calls fetchAntigravityLatestVersion() while holding the write lock, and that fetch can block on network I/O up to the 10-second timeout. Because this function is used by resolveUserAgent() on the request path, concurrent requests can stall behind the lock at cold start and each cache refresh window. Refreshing outside the critical section (or serving stale while refreshing) avoids periodic head-of-line latency spikes.

Useful? React with 👍 / 👎.

@luispater luispater changed the base branch from main to dev April 4, 2026 13:00
@luispater luispater merged commit 2ee938a into router-for-me:dev Apr 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants