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  }