fix(global/external): watchMounted 加锁读取 Mounted map#254
Open
fix(global/external): watchMounted 加锁读取 Mounted map#254
Conversation
The fsnotify watcher goroutine in watchMounted called m.getMounted() (which takes m.mu.Lock) and then immediately read m.Mounted directly, plus printed `m.Mounted` in several log statements. Concurrent getMounted() / Updated() (cron, every 5min) writes the map at the same time, which the Go runtime treats as a map race and can fatal the process. Add two helpers (hasMount, snapshotMountedJSON) that take m.mu.RLock() and use them everywhere watchMounted previously touched the map. The format-string log lines now print a stable copy taken under the read lock, so we can no longer print a map that's being modified. Co-authored-by: Cursor <cursoragent@cursor.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
概要
`pkg/global/external.go` 的 `watchMounted` goroutine 在调用 `m.getMounted()`(内部已 `mu.Lock`)之后,立刻 不持锁 直接读 `m.Mounted[...]`,并把整个 `m.Mounted` 当作 `%+v` 打到日志。同一时刻 cron 每 5 分钟一次的 `Updated()` 也会进 `getMounted` 重建 map。
Go runtime 对并发 map 读写会直接 `fatal error: concurrent map read and map write`,进程会被打挂;即便不 fatal,日志里也可能拿到一个正在被替换的 map。
改动
新增两个辅助方法,全部在 RLock 下完成:
`watchMounted` 中所有直接访问 `m.Mounted` 的地方都改用这两个方法。
验证方式
Made with Cursor