Skip to content

Commit ad0c416

Browse files
committed
fix data race issue from test
1 parent b3f1489 commit ad0c416

File tree

4 files changed

+35
-38
lines changed

4 files changed

+35
-38
lines changed

backend/instancemgmt/instance_manager.go

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ var (
1818
Name: "active_instances",
1919
Help: "The number of active plugin instances",
2020
})
21-
disposeTTL = 5 * time.Second
2221
)
2322

23+
const defaultDisposeTTL = 5 * time.Second // Time to wait before disposing an instance
24+
2425
// Instance is a marker interface for an instance.
2526
type Instance interface{}
2627

@@ -73,21 +74,33 @@ type InstanceProvider interface {
7374

7475
// New create a new instance manager.
7576
func New(provider InstanceProvider) InstanceManager {
77+
return newInstanceManager(provider, defaultDisposeTTL)
78+
}
79+
80+
func newInstanceManager(provider InstanceProvider, disposeTTL time.Duration) *instanceManager {
7681
if provider == nil {
7782
panic("provider cannot be nil")
7883
}
7984

85+
if disposeTTL <= 0 {
86+
disposeTTL = defaultDisposeTTL
87+
}
88+
8089
return &instanceManager{
81-
provider: provider,
82-
cache: sync.Map{},
83-
locker: newLocker(),
90+
provider: provider,
91+
cache: sync.Map{},
92+
locker: newLocker(),
93+
disposeTTL: disposeTTL,
8494
}
8595
}
8696

8797
type instanceManager struct {
88-
locker *locker
89-
provider InstanceProvider
90-
cache sync.Map
98+
locker *locker
99+
provider InstanceProvider
100+
cache sync.Map
101+
disposeTTL time.Duration
102+
103+
disposeMutex sync.Mutex // Mutex to protect disposeTTL access in tests
91104
}
92105

93106
func (im *instanceManager) Get(ctx context.Context, pluginContext backend.PluginContext) (Instance, error) {
@@ -121,7 +134,7 @@ func (im *instanceManager) Get(ctx context.Context, pluginContext backend.Plugin
121134
}
122135

123136
if disposer, valid := ci.instance.(InstanceDisposer); valid {
124-
time.AfterFunc(disposeTTL, func() {
137+
time.AfterFunc(im.disposeTTL, func() {
125138
disposer.Dispose()
126139
activeInstances.Dec()
127140
})
@@ -157,6 +170,14 @@ func (im *instanceManager) Do(ctx context.Context, pluginContext backend.PluginC
157170
return nil
158171
}
159172

173+
// setDisposeTTL sets the TTL for disposing instances.
174+
// This method is only used for testing purposes to control the dispose timing behavior.
175+
func (im *instanceManager) setDisposeTTL(ttl time.Duration) {
176+
im.disposeMutex.Lock()
177+
defer im.disposeMutex.Unlock()
178+
im.disposeTTL = ttl
179+
}
180+
160181
func callInstanceHandlerFunc(fn InstanceCallbackFunc, instance interface{}) {
161182
var params = []reflect.Value{}
162183
params = append(params, reflect.ValueOf(instance))

backend/instancemgmt/instance_manager_test.go

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func TestInstanceManager(t *testing.T) {
2222
}
2323

2424
tip := &testInstanceProvider{}
25-
im := New(tip)
25+
im := newInstanceManager(tip, time.Millisecond)
2626

2727
t.Run("When getting instance should create a new instance", func(t *testing.T) {
2828
instance, err := im.Get(ctx, pCtx)
@@ -44,11 +44,6 @@ func TestInstanceManager(t *testing.T) {
4444
Updated: time.Now(),
4545
},
4646
}
47-
origDisposeTTL := disposeTTL
48-
disposeTTL = time.Millisecond
49-
t.Cleanup(func() {
50-
disposeTTL = origDisposeTTL
51-
})
5247
newInstance, err := im.Get(ctx, pCtxUpdated)
5348

5449
t.Run("New instance should be created", func(t *testing.T) {
@@ -111,12 +106,6 @@ func TestInstanceManagerConcurrency(t *testing.T) {
111106
})
112107

113108
t.Run("Check possible race condition issues when re-creating instance on settings update", func(t *testing.T) {
114-
origDisposeTTL := disposeTTL
115-
disposeTTL = time.Millisecond
116-
t.Cleanup(func() {
117-
disposeTTL = origDisposeTTL
118-
})
119-
120109
ctx := context.Background()
121110
initialPCtx := backend.PluginContext{
122111
OrgID: 1,
@@ -125,7 +114,8 @@ func TestInstanceManagerConcurrency(t *testing.T) {
125114
},
126115
}
127116
tip := &testInstanceProvider{}
128-
im := New(tip)
117+
im := New(tip).(*instanceManager)
118+
im.setDisposeTTL(time.Millisecond)
129119
// Creating initial instance with old contexts
130120
instanceToDispose, _ := im.Get(ctx, initialPCtx)
131121

backend/instancemgmt/intance_manager_ttl.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,9 @@ func newTTLInstanceManager(provider InstanceProvider, instanceTTL, instanceClean
3333
cache.OnEvicted(func(_ string, value interface{}) {
3434
ci := value.(CachedInstance)
3535
if disposer, valid := ci.instance.(InstanceDisposer); valid {
36-
time.AfterFunc(disposeTTL, func() {
37-
disposer.Dispose()
38-
activeInstances.Dec()
39-
})
40-
} else {
41-
activeInstances.Dec()
36+
disposer.Dispose()
4237
}
38+
activeInstances.Dec()
4339
})
4440

4541
return &instanceManagerWithTTL{

backend/instancemgmt/intance_manager_ttl_test.go

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,7 @@ func TestTTLInstanceManager(t *testing.T) {
4343
Updated: time.Now(),
4444
},
4545
}
46-
origDisposeTTL := disposeTTL
47-
disposeTTL = time.Millisecond
48-
t.Cleanup(func() {
49-
disposeTTL = origDisposeTTL
50-
})
46+
5147
newInstance, err := im.Get(ctx, pCtxUpdated)
5248

5349
t.Run("New instance should be created", func(t *testing.T) {
@@ -192,12 +188,6 @@ func TestTTLInstanceManagerConcurrency(t *testing.T) {
192188
})
193189

194190
t.Run("Check possible race condition issues when re-creating instance on settings update", func(t *testing.T) {
195-
origDisposeTTL := disposeTTL
196-
disposeTTL = time.Millisecond
197-
t.Cleanup(func() {
198-
disposeTTL = origDisposeTTL
199-
})
200-
201191
ctx := context.Background()
202192
initialPCtx := backend.PluginContext{
203193
OrgID: 1,

0 commit comments

Comments
 (0)