Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions pkg/api/webassets/webassets.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"os"
"path/filepath"
"sync"

"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/services/licensing"
Expand All @@ -31,12 +32,21 @@ type EntryPointInfo struct {
} `json:"assets,omitempty"`
}

var entryPointAssetsCache *dtos.EntryPointAssets = nil
var (
entryPointAssetsCacheMu sync.RWMutex // guard entryPointAssetsCache
entryPointAssetsCache *dtos.EntryPointAssets // TODO: get rid of global state
)

func GetWebAssets(ctx context.Context, cfg *setting.Cfg, license licensing.Licensing) (*dtos.EntryPointAssets, error) {
if cfg.Env != setting.Dev && entryPointAssetsCache != nil {
return entryPointAssetsCache, nil
entryPointAssetsCacheMu.RLock()
ret := entryPointAssetsCache
entryPointAssetsCacheMu.RUnlock()

if cfg.Env != setting.Dev && ret != nil {
return ret, nil
}
entryPointAssetsCacheMu.Lock()
defer entryPointAssetsCacheMu.Unlock()
Comment on lines +41 to +49
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Incomplete double-checked locking pattern.

After releasing the read lock (line 43) and before acquiring the write lock (line 48), another goroutine may have already updated the cache. Without a second check after acquiring the write lock, multiple concurrent callers could redundantly perform the expensive asset-reading operation.

Apply this diff to complete the double-checked locking pattern:

 	entryPointAssetsCacheMu.Lock()
 	defer entryPointAssetsCacheMu.Unlock()
+
+	// Double-check: another goroutine may have updated the cache
+	if cfg.Env != setting.Dev && entryPointAssetsCache != nil {
+		return entryPointAssetsCache, nil
+	}

 	var err error
🤖 Prompt for AI Agents
In pkg/api/webassets/webassets.go around lines 41 to 49, the double-checked
locking is incomplete: after releasing the read lock and before acquiring the
write lock another goroutine may have populated entryPointAssetsCache. Update
the code to re-check entryPointAssetsCache after acquiring the write lock and if
it's now non-nil (and cfg.Env != setting.Dev) return it immediately; only
proceed with the expensive asset-reading and assignment when the cache is still
nil (or env requires reload). Ensure the write-lock is held while assigning
entryPointAssetsCache and that defer entryPointAssetsCacheMu.Unlock() remains in
place.


var err error
var result *dtos.EntryPointAssets
Expand Down
Loading