👾 Description
The cachedFetcher.update() function in token/services/selector/sherdlock/fetcher.go holds a write lock (f.mu.Lock()) for the
entire duration of the database query when refreshing the token cache. This causes all concurrent token read operations to block
during the refresh, creating a performance bottleneck.
Severity: Medium
Type: Concurrency / Performance Bug
🛠️ Steps to reproduce
- Set up a Fabric Token SDK environment with sherdlock selector
- Configure a slow database or add artificial delay to
SpendableTokensIteratorBy
- Trigger a cache refresh (wait for
freshnessInterval to expire or set maxQueriesBeforeRefresh to low value)
- While cache is refreshing, attempt token read operations via
UnspentTokensIteratorBy
- Observe that read operations block until the DB query completes
📋 Logs and Screenshots
No response
🌐 Network Environment
Other
📦 Fabric Token SDK Version
v0.10.x or latest main
🐹 Go Version
1.24
💻 Operating System
Windows (WSL2)
➕ Additional context
Root Cause Location: token/services/selector/sherdlock/fetcher.go - update() function
Affected Code Pattern:
func (f *cachedFetcher) update(ctx context.Context) {
f.mu.Lock()
defer f.mu.Unlock() // Lock held during slow DB call
// ...
it, err := f.tokenDB.SpendableTokensIteratorBy(ctx, "", "") // Blocks all readers
}
Proposed Fix: Release lock before DB call, re-acquire and re-check staleness after, then update cache atomically.
Related PR: #1535
Impact: Performance degradation only — no correctness issue. Token operations eventually complete, but latency spikes during cache
refresh.
Labels: bug, performance, concurrency, sherdlock
👾 Description
The
cachedFetcher.update()function intoken/services/selector/sherdlock/fetcher.goholds a write lock (f.mu.Lock()) for theentire duration of the database query when refreshing the token cache. This causes all concurrent token read operations to block
during the refresh, creating a performance bottleneck.
Severity: Medium
Type: Concurrency / Performance Bug
🛠️ Steps to reproduce
SpendableTokensIteratorByfreshnessIntervalto expire or setmaxQueriesBeforeRefreshto low value)UnspentTokensIteratorBy📋 Logs and Screenshots
No response
🌐 Network Environment
Other
📦 Fabric Token SDK Version
v0.10.x or latest main
🐹 Go Version
1.24
💻 Operating System
Windows (WSL2)
➕ Additional context
Root Cause Location:
token/services/selector/sherdlock/fetcher.go-update()functionAffected Code Pattern: