From d2dcc145ae99341c4aceca8b8f1e900d44782a75 Mon Sep 17 00:00:00 2001 From: Daniel Bennett Date: Thu, 6 Apr 2023 13:03:36 -0500 Subject: [PATCH] lock instances, Timer differently, remove debris --- client/dynamicplugins/registry.go | 34 +++++++++++++++++----- client/pluginmanager/csimanager/manager.go | 2 ++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/client/dynamicplugins/registry.go b/client/dynamicplugins/registry.go index 8e04ff80ad02..497459731d9a 100644 --- a/client/dynamicplugins/registry.go +++ b/client/dynamicplugins/registry.go @@ -10,6 +10,8 @@ import ( "fmt" "sync" "time" + + "github.com/hashicorp/nomad/helper" ) const ( @@ -308,6 +310,23 @@ func (d *dynamicRegistry) ListPlugins(ptype string) []*PluginInfo { // Callers should pass in a context with a sensible timeout // for the plugin they're expecting to find. func (d *dynamicRegistry) WaitForPlugin(ctx context.Context, ptype, name string) (*PluginInfo, error) { + // this is our actual goal, which may be run repeatedly + findPlugin := func() *PluginInfo { + for _, p := range d.ListPlugins(ptype) { + if p.Name == name { + return p + } + } + return nil + } + + // try immediately first, before any timers get involved + if p := findPlugin(); p != nil { + return p, nil + } + + // next, loop until found or context is done + // these numbers are almost arbitrary... delay := 200 // milliseconds between checks, will backoff maxDelay := 5000 // up to 5 seconds between each check @@ -317,15 +336,9 @@ func (d *dynamicRegistry) WaitForPlugin(ctx context.Context, ptype, name string) ctx, cancel := context.WithTimeout(ctx, 24*time.Hour) defer cancel() - timer := time.NewTimer(time.Duration(delay) * time.Millisecond) + timer, stop := helper.NewSafeTimer(time.Duration(delay) * time.Millisecond) + defer stop() for { - for _, p := range d.ListPlugins(ptype) { - if p.Name == name { - return p, nil - } - } - - //log.Printf("WaitForPlugin delay: %d", delay) // TODO: get a logger in here? select { case <-ctx.Done(): // an externally-defined timeout wins the day @@ -333,6 +346,11 @@ func (d *dynamicRegistry) WaitForPlugin(ctx context.Context, ptype, name string) case <-timer.C: // continue after our internal delay } + + if p := findPlugin(); p != nil { + return p, nil + } + if delay < maxDelay { delay += delay } diff --git a/client/pluginmanager/csimanager/manager.go b/client/pluginmanager/csimanager/manager.go index 8a11f01930be..76f49eda995c 100644 --- a/client/pluginmanager/csimanager/manager.go +++ b/client/pluginmanager/csimanager/manager.go @@ -84,6 +84,8 @@ func (c *csiManager) WaitForPlugin(ctx context.Context, pType, pID string) error if err != nil { return fmt.Errorf("%s plugin '%s' did not become ready: %w", pType, pID, err) } + c.instancesLock.Lock() + defer c.instancesLock.Unlock() c.ensureInstance(p) return nil }