github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/connection/refresh_connections.go (about) 1 package connection 2 3 import ( 4 "context" 5 "log" 6 "sync" 7 "time" 8 9 "github.com/turbot/go-kit/helpers" 10 "github.com/turbot/steampipe/pkg/steampipeconfig" 11 ) 12 13 // only allow one execution of refresh connections 14 var executeLock sync.Mutex 15 16 // only allow one queued execution 17 var queueLock sync.Mutex 18 19 func RefreshConnections(ctx context.Context, pluginManager pluginManager, forceUpdateConnectionNames ...string) (res *steampipeconfig.RefreshConnectionResult) { 20 log.Println("[INFO] RefreshConnections start") 21 defer log.Println("[INFO] RefreshConnections end") 22 23 // TODO KAI if we, for example, access a nil map, this does not seem to catch it and startup hangs 24 defer func() { 25 if r := recover(); r != nil { 26 res = steampipeconfig.NewErrorRefreshConnectionResult(helpers.ToError(r)) 27 } 28 }() 29 30 t := time.Now() 31 defer log.Printf("[INFO] refreshConnections completion time (%fs)", time.Since(t).Seconds()) 32 33 // first grab the queue lock 34 if !queueLock.TryLock() { 35 // someone has it - they will execute so we have nothing to do 36 log.Printf("[INFO] another execution is already queued - returning") 37 return &steampipeconfig.RefreshConnectionResult{} 38 } 39 40 log.Printf("[INFO] acquired refreshQueueLock, try to acquire refreshExecuteLock") 41 42 // so we have the queue lock, now wait on the execute lock 43 executeLock.Lock() 44 defer func() { 45 executeLock.Unlock() 46 log.Printf("[INFO] released refreshExecuteLock") 47 }() 48 49 // we have the execute-lock, release the queue-lock so someone else can queue 50 queueLock.Unlock() 51 log.Printf("[INFO] acquired refreshExecuteLock, released refreshQueueLock") 52 53 // now refresh connections 54 55 // package up all necessary data into a state object 56 state, err := newRefreshConnectionState(ctx, pluginManager, forceUpdateConnectionNames) 57 if err != nil { 58 return steampipeconfig.NewErrorRefreshConnectionResult(err) 59 } 60 61 // now do the refresh 62 state.refreshConnections(ctx) 63 64 return state.res 65 }