@@ -6,15 +6,12 @@ import (
66 "log/slog"
77 "strings"
88 "sync"
9- "sync/atomic"
109 "time"
1110
1211 "github.com/muesli/cache2go"
1312 "github.com/shurcooL/githubv4"
1413)
1514
16- var cacheNameCounter atomic.Uint64
17-
1815// RepoAccessCache caches repository metadata related to lockdown checks so that
1916// multiple tools can reuse the same access information safely across goroutines.
2017type RepoAccessCache struct {
@@ -28,7 +25,6 @@ type RepoAccessCache struct {
2825type repoAccessCacheEntry struct {
2926 isPrivate bool
3027 knownUsers map [string ]bool // normalized login -> has push access
31- ready bool
3228}
3329
3430const defaultRepoAccessTTL = 5 * time .Minute
@@ -55,7 +51,7 @@ func WithLogger(logger *slog.Logger) RepoAccessOption {
5551// client. The cache is safe for concurrent use.
5652func NewRepoAccessCache (client * githubv4.Client , opts ... RepoAccessOption ) * RepoAccessCache {
5753 // Use a unique cache name for each instance to avoid sharing state between tests
58- cacheName := fmt . Sprintf ( "repoAccess-%d" , cacheNameCounter . Add ( 1 ))
54+ cacheName := "repo-access-cache"
5955 c := & RepoAccessCache {
6056 client : client ,
6157 cache : cache2go .Cache (cacheName ),
@@ -77,16 +73,16 @@ func (c *RepoAccessCache) SetTTL(ttl time.Duration) {
7773 defer c .mu .Unlock ()
7874 c .ttl = ttl
7975 c .logInfo ("repo access cache TTL updated" , "ttl" , ttl )
80-
76+
8177 // Collect all current entries
8278 entries := make (map [interface {}]* repoAccessCacheEntry )
8379 c .cache .Foreach (func (key interface {}, item * cache2go.CacheItem ) {
8480 entries [key ] = item .Data ().(* repoAccessCacheEntry )
8581 })
86-
82+
8783 // Flush the cache
8884 c .cache .Flush ()
89-
85+
9086 // Re-add all entries with the new TTL
9187 for key , entry := range entries {
9288 c .cache .Add (key , ttl , entry )
@@ -119,16 +115,14 @@ func (c *RepoAccessCache) GetRepoAccessInfo(ctx context.Context, username, owner
119115 userKey := strings .ToLower (username )
120116 c .mu .Lock ()
121117 defer c .mu .Unlock ()
122-
118+
123119 // Try to get entry from cache - this will keep the item alive if it exists
124120 cacheItem , err := c .cache .Value (key )
125121 if err == nil {
126122 entry := cacheItem .Data ().(* repoAccessCacheEntry )
127- if entry .ready {
128- if cachedHasPush , known := entry .knownUsers [userKey ]; known {
129- c .logDebug ("repo access cache hit" , "owner" , owner , "repo" , repo , "user" , username )
130- return entry .isPrivate , cachedHasPush , nil
131- }
123+ if cachedHasPush , known := entry .knownUsers [userKey ]; known {
124+ c .logDebug ("repo access cache hit" , "owner" , owner , "repo" , repo , "user" , username )
125+ return entry .isPrivate , cachedHasPush , nil
132126 }
133127 // Entry exists but user not in knownUsers, need to query
134128 }
@@ -139,26 +133,22 @@ func (c *RepoAccessCache) GetRepoAccessInfo(ctx context.Context, username, owner
139133 return false , false , queryErr
140134 }
141135
142- // Get or create entry - don't use Value() here to avoid keeping alive unnecessarily
136+ // Repo access info retrieved, update or create cache entry
143137 var entry * repoAccessCacheEntry
144138 if err == nil && cacheItem != nil {
145- // Entry already existed, just update it
146139 entry = cacheItem .Data ().(* repoAccessCacheEntry )
147- } else {
148- // Create new entry
149- entry = & repoAccessCacheEntry {
150- knownUsers : make (map [string ]bool ),
151- }
140+ entry .knownUsers [userKey ] = hasPush
141+ return entry .isPrivate , entry .knownUsers [userKey ], nil
142+ }
143+
144+ // Create new entry
145+ entry = & repoAccessCacheEntry {
146+ knownUsers : map [string ]bool {userKey : hasPush },
147+ isPrivate : isPrivate ,
152148 }
153-
154- entry .ready = true
155- entry .isPrivate = isPrivate
156- entry .knownUsers [userKey ] = hasPush
157-
158- // Add or update the entry in cache with TTL
159149 c .cache .Add (key , c .ttl , entry )
160150
161- return isPrivate , hasPush , nil
151+ return entry . isPrivate , entry . knownUsers [ userKey ] , nil
162152}
163153
164154func (c * RepoAccessCache ) queryRepoAccessInfo (ctx context.Context , username , owner , repo string ) (bool , bool , error ) {
@@ -207,14 +197,6 @@ func cacheKey(owner, repo string) string {
207197 return fmt .Sprintf ("%s/%s" , strings .ToLower (owner ), strings .ToLower (repo ))
208198}
209199
210- func splitKey (key string ) (string , string ) {
211- owner , rest , found := strings .Cut (key , "/" )
212- if ! found {
213- return key , ""
214- }
215- return owner , rest
216- }
217-
218200func (c * RepoAccessCache ) logDebug (msg string , args ... any ) {
219201 if c != nil && c .logger != nil {
220202 c .logger .Debug (msg , args ... )
0 commit comments