github.com/Axway/agent-sdk@v1.1.101/pkg/jobs/intervaljob.go (about) 1 package jobs 2 3 import ( 4 "time" 5 ) 6 7 type intervalJobProps struct { 8 interval time.Duration 9 stopChan chan bool 10 } 11 12 type intervalJob struct { 13 baseJob 14 intervalJobProps 15 } 16 17 // newIntervalJob - creates an interval run job 18 func newIntervalJob(newJob Job, interval time.Duration, name string, failJobChan chan string, opts ...jobOpt) (JobExecution, error) { 19 thisJob := intervalJob{ 20 createBaseJob(newJob, failJobChan, name, JobTypeInterval), 21 intervalJobProps{ 22 interval: interval, 23 stopChan: make(chan bool, 1), 24 }, 25 } 26 27 for _, o := range opts { 28 o(&thisJob.baseJob) 29 } 30 31 go thisJob.start() 32 return &thisJob, nil 33 } 34 35 func (b *intervalJob) handleExecution() { 36 // Execute the job now and then start the interval period 37 b.executeCronJob() 38 if b.getError() != nil { 39 b.setExecutionError() 40 b.logger.Error(b.getError()) 41 b.setConsecutiveFails(b.getConsecutiveFails() + 1) 42 return 43 } 44 b.setConsecutiveFails(0) 45 } 46 47 // start - calls the Execute function from the Job definition 48 func (b *intervalJob) start() { 49 b.startLog() 50 b.waitForReady() 51 52 // This could happen while rescheduling the job, pool tries to start 53 // and one of the job fails which triggers stop setting the flag to not ready 54 // Return in this case to allow pool to reschedule the job 55 if !b.IsReady() { 56 return 57 } 58 59 b.setIsStopped(false) 60 b.SetStatus(JobStatusRunning) 61 62 // Execute the job now and then start the interval period 63 b.handleExecution() 64 65 ticker := time.NewTicker(b.interval) 66 defer ticker.Stop() 67 for { 68 // Non-blocking channel read, if stopped then exit 69 select { 70 case <-b.stopChan: 71 b.SetStatus(JobStatusStopped) 72 return 73 case <-ticker.C: 74 b.handleExecution() 75 ticker.Stop() 76 ticker = time.NewTicker(b.interval) 77 } 78 } 79 } 80 81 // stop - write to the stop channel to stop the execution loop 82 func (b *intervalJob) stop() { 83 if b.getIsStopped() { 84 b.logger.Tracef("job has already been stopped") 85 return 86 } 87 b.stopLog() 88 if b.IsReady() { 89 b.logger.Tracef("writing to %s stop channel", b.GetName()) 90 b.stopChan <- true 91 b.logger.Tracef("wrote to %s stop channel", b.GetName()) 92 b.UnsetIsReady() 93 } else { 94 b.stopReadyIfWaiting(0) 95 } 96 b.setIsStopped(true) 97 }