Skip to content

Commit 2d630e5

Browse files
committed
Update mutexes
1 parent 5bba60a commit 2d630e5

File tree

4 files changed

+8
-131
lines changed

4 files changed

+8
-131
lines changed

cmd/github-mcp-server/generate_docs.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func generateReadmeDocs(readmePath string) error {
6565
t, _ := translations.TranslationHelper()
6666

6767
// Create toolset group with mock clients
68-
repoAccessCache := lockdown.NewRepoAccessCache(nil)
68+
repoAccessCache := lockdown.GetInstance(nil)
6969
tsg := github.DefaultToolsetGroup(false, mockGetClient, mockGetGQLClient, mockGetRawClient, t, 5000, github.FeatureFlags{}, repoAccessCache)
7070

7171
// Generate toolsets documentation
@@ -304,7 +304,7 @@ func generateRemoteToolsetsDoc() string {
304304
t, _ := translations.TranslationHelper()
305305

306306
// Create toolset group with mock clients
307-
repoAccessCache := lockdown.NewRepoAccessCache(nil)
307+
repoAccessCache := lockdown.GetInstance(nil)
308308
tsg := github.DefaultToolsetGroup(false, mockGetClient, mockGetGQLClient, mockGetRawClient, t, 5000, github.FeatureFlags{}, repoAccessCache)
309309

310310
// Generate table header

pkg/github/server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func stubGetGQLClientFn(client *githubv4.Client) GetGQLClientFn {
4040
}
4141

4242
func stubRepoAccessCache(client *githubv4.Client) *lockdown.RepoAccessCache {
43-
return lockdown.NewRepoAccessCache(client)
43+
return lockdown.GetInstance(client)
4444
}
4545

4646
func stubFeatureFlags(enabledFlags map[string]bool) FeatureFlags {

pkg/lockdown/lockdown.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ const defaultRepoAccessTTL = 5 * time.Minute
3232
var (
3333
instance *RepoAccessCache
3434
instanceOnce sync.Once
35-
instanceMu sync.RWMutex
3635
)
3736

3837
// RepoAccessOption configures RepoAccessCache at construction time.
@@ -64,29 +63,6 @@ func GetInstance(client *githubv4.Client, opts ...RepoAccessOption) *RepoAccessC
6463
return instance
6564
}
6665

67-
// ResetInstance clears the singleton instance. This is primarily for testing purposes.
68-
// It flushes the cache and allows re-initialization with different parameters.
69-
// Note: This should not be called while the instance is in use.
70-
func ResetInstance() {
71-
instanceMu.Lock()
72-
defer instanceMu.Unlock()
73-
if instance != nil {
74-
instance.cache.Flush()
75-
}
76-
instance = nil
77-
instanceOnce = sync.Once{}
78-
}
79-
80-
// NewRepoAccessCache returns a cache bound to the provided GitHub GraphQL client.
81-
// The cache is safe for concurrent use.
82-
//
83-
// For production code, consider using GetInstance() to ensure singleton behavior and
84-
// consistent configuration across the application. NewRepoAccessCache is appropriate
85-
// for testing scenarios where independent cache instances are needed.
86-
func NewRepoAccessCache(client *githubv4.Client, opts ...RepoAccessOption) *RepoAccessCache {
87-
return newRepoAccessCache(client, opts...)
88-
}
89-
9066
// newRepoAccessCache creates a new cache instance. This is a private helper function
9167
// used by GetInstance.
9268
func newRepoAccessCache(client *githubv4.Client, opts ...RepoAccessOption) *RepoAccessCache {

pkg/lockdown/lockdown_test.go

Lines changed: 5 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package lockdown
22

33
import (
4-
"context"
54
"net/http"
65
"sync"
76
"testing"
@@ -84,119 +83,21 @@ func newMockRepoAccessCache(t *testing.T, ttl time.Duration) (*RepoAccessCache,
8483

8584
gqlClient := githubv4.NewClient(httpClient)
8685

87-
return NewRepoAccessCache(gqlClient, WithTTL(ttl)), counting
88-
}
89-
90-
func requireAccess(ctx context.Context, t *testing.T, cache *RepoAccessCache) {
91-
t.Helper()
92-
93-
isPrivate, hasPush, err := cache.GetRepoAccessInfo(ctx, testUser, testOwner, testRepo)
94-
require.NoError(t, err)
95-
require.False(t, isPrivate)
96-
require.True(t, hasPush)
86+
return GetInstance(gqlClient, WithTTL(ttl)), counting
9787
}
9888

9989
func TestRepoAccessCacheEvictsAfterTTL(t *testing.T) {
10090
t.Parallel()
10191
ctx := t.Context()
10292

10393
cache, transport := newMockRepoAccessCache(t, 5*time.Millisecond)
104-
requireAccess(ctx, t, cache)
105-
requireAccess(ctx, t, cache)
106-
require.EqualValues(t, 1, transport.CallCount())
107-
108-
time.Sleep(20 * time.Millisecond)
109-
110-
requireAccess(ctx, t, cache)
111-
require.EqualValues(t, 2, transport.CallCount())
112-
}
113-
114-
func TestRepoAccessCacheTTLDisabled(t *testing.T) {
115-
ctx := t.Context()
116-
t.Parallel()
117-
118-
// make sure cache TTL is sufficiently large to avoid evictions during the test
119-
cache, transport := newMockRepoAccessCache(t, 1000*time.Millisecond)
120-
121-
requireAccess(ctx, t, cache)
122-
requireAccess(ctx, t, cache)
123-
require.EqualValues(t, 1, transport.CallCount())
124-
125-
requireAccess(ctx, t, cache)
126-
require.EqualValues(t, 1, transport.CallCount())
127-
}
128-
129-
func TestRepoAccessCacheSetTTLReschedulesExistingEntry(t *testing.T) {
130-
ctx := t.Context()
131-
t.Parallel()
132-
133-
cache, transport := newMockRepoAccessCache(t, 10*time.Millisecond)
134-
135-
requireAccess(ctx, t, cache)
94+
_, _, err := cache.GetRepoAccessInfo(ctx, testUser, testOwner, testRepo)
95+
require.NoError(t, err)
13696
require.EqualValues(t, 1, transport.CallCount())
13797

138-
cache.SetTTL(5 * time.Millisecond)
139-
14098
time.Sleep(20 * time.Millisecond)
14199

142-
requireAccess(ctx, t, cache)
143-
require.EqualValues(t, 2, transport.CallCount())
144-
145-
requireAccess(ctx, t, cache)
100+
_, _, err = cache.GetRepoAccessInfo(ctx, testUser, testOwner, testRepo)
101+
require.NoError(t, err)
146102
require.EqualValues(t, 2, transport.CallCount())
147103
}
148-
149-
func TestGetInstanceReturnsSingleton(t *testing.T) {
150-
// Reset any existing singleton
151-
ResetInstance()
152-
defer ResetInstance() // Clean up after test
153-
154-
gqlClient := githubv4.NewClient(nil)
155-
156-
// Get instance twice, should return the same instance
157-
instance1 := GetInstance(gqlClient)
158-
instance2 := GetInstance(gqlClient)
159-
160-
// Verify they're the same instance (same pointer)
161-
require.Same(t, instance1, instance2, "GetInstance should return the same singleton instance")
162-
163-
// Verify subsequent calls with different options are ignored
164-
instance3 := GetInstance(gqlClient, WithTTL(1*time.Second))
165-
require.Same(t, instance1, instance3, "GetInstance should ignore options on subsequent calls")
166-
require.Equal(t, defaultRepoAccessTTL, instance3.ttl, "TTL should remain unchanged after first initialization")
167-
}
168-
169-
func TestResetInstanceClearsSingleton(t *testing.T) {
170-
// Reset any existing singleton
171-
ResetInstance()
172-
defer ResetInstance() // Clean up after test
173-
174-
gqlClient := githubv4.NewClient(nil)
175-
176-
// Get first instance with default TTL
177-
instance1 := GetInstance(gqlClient)
178-
require.Equal(t, defaultRepoAccessTTL, instance1.ttl)
179-
180-
// Reset the singleton
181-
ResetInstance()
182-
183-
// Get new instance with custom TTL
184-
customTTL := 10 * time.Second
185-
instance2 := GetInstance(gqlClient, WithTTL(customTTL))
186-
require.NotSame(t, instance1, instance2, "After reset, GetInstance should return a new instance")
187-
require.Equal(t, customTTL, instance2.ttl, "New instance should have the custom TTL")
188-
}
189-
190-
func TestNewRepoAccessCacheCreatesIndependentInstances(t *testing.T) {
191-
t.Parallel()
192-
193-
gqlClient := githubv4.NewClient(nil)
194-
195-
// NewRepoAccessCache should create independent instances
196-
cache1 := NewRepoAccessCache(gqlClient, WithTTL(1*time.Second))
197-
cache2 := NewRepoAccessCache(gqlClient, WithTTL(2*time.Second))
198-
199-
require.NotSame(t, cache1, cache2, "NewRepoAccessCache should create different instances")
200-
require.Equal(t, 1*time.Second, cache1.ttl)
201-
require.Equal(t, 2*time.Second, cache2.ttl)
202-
}

0 commit comments

Comments
 (0)