github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/model/job/trigger_at.go (about) 1 package job 2 3 import ( 4 "time" 5 ) 6 7 // maxPastTriggerTime is the maximum duration in the past for which the at 8 // triggers are executed immediately instead of discarded. 9 var maxPastTriggerTime = 24 * time.Hour 10 11 // AtTrigger implements the @at trigger type. It schedules a job at a specified 12 // time in the future. 13 type AtTrigger struct { 14 *TriggerInfos 15 at time.Time 16 done chan struct{} 17 } 18 19 // NewAtTrigger returns a new instance of AtTrigger given the specified 20 // options. 21 func NewAtTrigger(infos *TriggerInfos) (*AtTrigger, error) { 22 at, err := time.Parse(time.RFC3339, infos.Arguments) 23 if err != nil { 24 return nil, ErrMalformedTrigger 25 } 26 return &AtTrigger{ 27 TriggerInfos: infos, 28 at: at, 29 done: make(chan struct{}), 30 }, nil 31 } 32 33 // NewInTrigger returns a new instance of AtTrigger given the specified 34 // options as @in. 35 func NewInTrigger(infos *TriggerInfos) (*AtTrigger, error) { 36 d, err := time.ParseDuration(infos.Arguments) 37 if err != nil { 38 return nil, ErrMalformedTrigger 39 } 40 at := time.Now().Add(d) 41 return &AtTrigger{ 42 TriggerInfos: infos, 43 at: at, 44 done: make(chan struct{}), 45 }, nil 46 } 47 48 // Type implements the Type method of the Trigger interface. 49 func (a *AtTrigger) Type() string { 50 return a.TriggerInfos.Type 51 } 52 53 // Schedule implements the Schedule method of the Trigger interface. 54 func (a *AtTrigger) Schedule() <-chan *JobRequest { 55 ch := make(chan *JobRequest) 56 go func() { 57 duration := -time.Since(a.at) 58 if duration < 0 { 59 if duration > -maxPastTriggerTime { 60 ch <- a.TriggerInfos.JobRequest() 61 } 62 close(ch) 63 return 64 } 65 select { 66 case <-time.After(duration): 67 ch <- a.TriggerInfos.JobRequest() 68 case <-a.done: 69 } 70 close(ch) 71 }() 72 return ch 73 } 74 75 // Unschedule implements the Unschedule method of the Trigger interface. 76 func (a *AtTrigger) Unschedule() { 77 close(a.done) 78 } 79 80 // Infos implements the Infos method of the Trigger interface. 81 func (a *AtTrigger) Infos() *TriggerInfos { 82 return a.TriggerInfos 83 } 84 85 // CombineRequest implements the CombineRequest method of the Trigger interface. 86 func (a *AtTrigger) CombineRequest() string { 87 return keepOriginalRequest 88 } 89 90 var _ Trigger = &AtTrigger{}