@@ -2,14 +2,15 @@ package instancemgmt
22
33import (
44"context"
5+ "fmt"
56"reflect"
6- "sync"
77"time"
88
99"github.com/prometheus/client_golang/prometheus"
1010"github.com/prometheus/client_golang/prometheus/promauto"
1111
1212"github.com/grafana/grafana-plugin-sdk-go/backend"
13+ gocache "github.com/patrickmn/go-cache"
1314)
1415
1516var (
1920Help : "The number of active plugin instances" ,
2021})
2122disposeTTL = 5 * time .Second
23+
24+ instanceTTL = 1 * time .Hour
25+ instanceCleanup = 2 * time .Hour
2226)
2327
2428// Instance is a marker interface for an instance.
@@ -76,18 +80,28 @@ func New(provider InstanceProvider) InstanceManager {
7680if provider == nil {
7781panic ("provider cannot be nil" )
7882}
83+ cache := gocache .New (instanceTTL , instanceCleanup )
84+ cache .OnEvicted (func (s 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+ })
7993
8094return & instanceManager {
8195provider : provider ,
82- cache : sync. Map {} ,
96+ cache : cache ,
8397locker : newLocker (),
8498}
8599}
86100
87101type instanceManager struct {
88102locker * locker
89103provider InstanceProvider
90- cache sync. Map
104+ cache * gocache. Cache
91105}
92106
93107func (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
96110return nil , err
97111}
98112// 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 )
102117
103118if ok {
104119ci := item .(CachedInstance )
@@ -109,35 +124,28 @@ func (im *instanceManager) Get(ctx context.Context, pluginContext backend.Plugin
109124}
110125}
111126
112- im .locker .Lock (cacheKey )
113- defer im .locker .Unlock (cacheKey )
127+ im .locker .Lock (strKey )
128+ defer im .locker .Unlock (strKey )
114129
115- if item , ok := im .cache .Load ( cacheKey ); ok {
130+ if item , ok := im .cache .Get ( strKey ); ok {
116131ci := item .(CachedInstance )
117132needsUpdate := im .provider .NeedsUpdate (ctx , pluginContext , ci )
118133
119134if ! needsUpdate {
120135return ci .instance , nil
121136}
122137
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 )
131139}
132140
133141instance , err := im .provider .NewInstance (ctx , pluginContext )
134142if err != nil {
135143return nil , err
136144}
137- im .cache .Store ( cacheKey , CachedInstance {
145+ im .cache .Set ( strKey , CachedInstance {
138146PluginContext : pluginContext ,
139147instance : instance ,
140- })
148+ }, gocache . DefaultExpiration )
141149activeInstances .Inc ()
142150
143151return instance , nil
0 commit comments