github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/component/coordinator.go (about) 1 package component 2 3 import ( 4 "context" 5 6 "code.cloudfoundry.org/lager/lagerctx" 7 "github.com/pf-qiu/concourse/v6/atc/db/lock" 8 ) 9 10 // Coordinator ensures that the given component is not executed concurrently. 11 type Coordinator struct { 12 Locker lock.LockFactory 13 Component Component 14 Runnable Runnable 15 } 16 17 func (coordinator *Coordinator) RunPeriodically(ctx context.Context) { 18 coordinator.run(ctx, false) 19 } 20 21 func (coordinator *Coordinator) RunImmediately(ctx context.Context) { 22 coordinator.run(ctx, true) 23 } 24 25 func (coordinator *Coordinator) run(ctx context.Context, immediate bool) { 26 logger := lagerctx.FromContext(ctx) 27 28 lockID := lock.NewTaskLockID(coordinator.Component.Name()) 29 30 lock, acquired, err := coordinator.Locker.Acquire(logger, lockID) 31 if err != nil { 32 logger.Error("failed-to-acquire-lock", err) 33 return 34 } 35 36 if !acquired { 37 logger.Debug("lock-unavailable") 38 return 39 } 40 41 defer lock.Release() 42 43 exists, err := coordinator.Component.Reload() 44 if err != nil { 45 logger.Error("failed-to-reload-component", err) 46 return 47 } 48 49 if !exists { 50 logger.Info("component-disappeared") 51 return 52 } 53 54 if coordinator.Component.Paused() { 55 logger.Debug("component-paused") 56 return 57 } 58 59 if !immediate && !coordinator.Component.IntervalElapsed() { 60 logger.Debug("interval-not-elapsed") 61 return 62 } 63 64 if err := coordinator.Runnable.Run(ctx); err != nil { 65 logger.Error("component-failed", err) 66 return 67 } 68 69 if err := coordinator.Component.UpdateLastRan(); err != nil { 70 logger.Error("failed-to-update-last-ran", err) 71 return 72 } 73 }