@@ -2,14 +2,15 @@ package instancemgmt
2
2
3
3
import (
4
4
"context"
5
+ "fmt"
5
6
"reflect"
6
- "sync"
7
7
"time"
8
8
9
9
"github.com/prometheus/client_golang/prometheus"
10
10
"github.com/prometheus/client_golang/prometheus/promauto"
11
11
12
12
"github.com/grafana/grafana-plugin-sdk-go/backend"
13
+ gocache "github.com/patrickmn/go-cache"
13
14
)
14
15
15
16
var (
19
20
Help : "The number of active plugin instances" ,
20
21
})
21
22
disposeTTL = 5 * time .Second
23
+
24
+ instanceTTL = 1 * time .Hour
25
+ instanceCleanup = 2 * time .Hour
22
26
)
23
27
24
28
// Instance is a marker interface for an instance.
@@ -76,18 +80,28 @@ func New(provider InstanceProvider) InstanceManager {
76
80
if provider == nil {
77
81
panic ("provider cannot be nil" )
78
82
}
83
+ cache := gocache .New (instanceTTL , instanceCleanup )
84
+ cache .OnEvicted (func (_ string , i interface {}) {
85
+ ci := i .(CachedInstance )
86
+ if disposer , valid := ci .instance .(InstanceDisposer ); valid {
87
+ time .AfterFunc (disposeTTL , func () {
88
+ disposer .Dispose ()
89
+ })
90
+ }
91
+ activeInstances .Dec ()
92
+ })
79
93
80
94
return & instanceManager {
81
95
provider : provider ,
82
- cache : sync. Map {} ,
96
+ cache : cache ,
83
97
locker : newLocker (),
84
98
}
85
99
}
86
100
87
101
type instanceManager struct {
88
102
locker * locker
89
103
provider InstanceProvider
90
- cache sync. Map
104
+ cache * gocache. Cache
91
105
}
92
106
93
107
func (im * instanceManager ) Get (ctx context.Context , pluginContext backend.PluginContext ) (Instance , error ) {
@@ -96,9 +110,10 @@ func (im *instanceManager) Get(ctx context.Context, pluginContext backend.Plugin
96
110
return nil , err
97
111
}
98
112
// Double-checked locking for update/create criteria
99
- im .locker .RLock (cacheKey )
100
- item , ok := im .cache .Load (cacheKey )
101
- im .locker .RUnlock (cacheKey )
113
+ strKey := fmt .Sprintf ("%v" , cacheKey )
114
+ im .locker .RLock (strKey )
115
+ item , ok := im .cache .Get (strKey )
116
+ im .locker .RUnlock (strKey )
102
117
103
118
if ok {
104
119
ci := item .(CachedInstance )
@@ -109,35 +124,28 @@ func (im *instanceManager) Get(ctx context.Context, pluginContext backend.Plugin
109
124
}
110
125
}
111
126
112
- im .locker .Lock (cacheKey )
113
- defer im .locker .Unlock (cacheKey )
127
+ im .locker .Lock (strKey )
128
+ defer im .locker .Unlock (strKey )
114
129
115
- if item , ok := im .cache .Load ( cacheKey ); ok {
130
+ if item , ok := im .cache .Get ( strKey ); ok {
116
131
ci := item .(CachedInstance )
117
132
needsUpdate := im .provider .NeedsUpdate (ctx , pluginContext , ci )
118
133
119
134
if ! needsUpdate {
120
135
return ci .instance , nil
121
136
}
122
137
123
- if disposer , valid := ci .instance .(InstanceDisposer ); valid {
124
- time .AfterFunc (disposeTTL , func () {
125
- disposer .Dispose ()
126
- activeInstances .Dec ()
127
- })
128
- } else {
129
- activeInstances .Dec ()
130
- }
138
+ im .cache .Delete (strKey )
131
139
}
132
140
133
141
instance , err := im .provider .NewInstance (ctx , pluginContext )
134
142
if err != nil {
135
143
return nil , err
136
144
}
137
- im .cache .Store ( cacheKey , CachedInstance {
145
+ im .cache .Set ( strKey , CachedInstance {
138
146
PluginContext : pluginContext ,
139
147
instance : instance ,
140
- })
148
+ }, gocache . DefaultExpiration )
141
149
activeInstances .Inc ()
142
150
143
151
return instance , nil
0 commit comments