Execute the our task function according to our schedule, until the given context gets cancelled.
(ctx context.Context)
| 26 | // Execute the our task function according to our schedule, until the given |
| 27 | // context gets cancelled. |
| 28 | func (t *Task) loop(ctx context.Context) { |
| 29 | // Kick off the task immediately (as long as the schedule is |
| 30 | // greater than zero, see below). |
| 31 | delay := immediately |
| 32 | |
| 33 | for { |
| 34 | var timer <-chan time.Time |
| 35 | |
| 36 | schedule, err := t.schedule() |
| 37 | switch { |
| 38 | case errors.Is(err, ErrSkip): |
| 39 | // Reset the delay to be exactly the schedule, so we |
| 40 | // rule out the case where it's set to immediately |
| 41 | // because it's the first iteration or we got reset. |
| 42 | delay = schedule |
| 43 | fallthrough // Fall to case nil, to apply normal non-error logic |
| 44 | case err == nil: |
| 45 | // If the schedule is greater than zero, setup a timer |
| 46 | // that will expire after 'delay' seconds (or after the |
| 47 | // schedule in case of ErrSkip, to avoid triggering |
| 48 | // immediately), otherwise setup a timer that will |
| 49 | // never expire (hence the task function won't ever be |
| 50 | // run, unless Reset() is called and schedule() starts |
| 51 | // returning values greater than zero). |
| 52 | if schedule > 0 { |
| 53 | timer = time.After(delay) |
| 54 | } else { |
| 55 | timer = make(chan time.Time) |
| 56 | } |
| 57 | |
| 58 | default: |
| 59 | // If the schedule is not greater than zero, abort the |
| 60 | // task and return immediately. Otherwise set up the |
| 61 | // timer to retry after that amount of time. |
| 62 | if schedule <= 0 { |
| 63 | return |
| 64 | } |
| 65 | |
| 66 | timer = time.After(schedule) |
| 67 | } |
| 68 | |
| 69 | select { |
| 70 | case <-timer: |
| 71 | if err == nil { |
| 72 | // Execute the task function synchronously. Consumers |
| 73 | // are responsible for implementing proper cancellation |
| 74 | // of the task function itself using the tomb's context. |
| 75 | start := time.Now() |
| 76 | t.f(ctx) |
| 77 | duration := time.Since(start) |
| 78 | |
| 79 | delay = schedule - duration |
| 80 | if delay < 0 { |
| 81 | delay = immediately |
| 82 | } |
| 83 | } else { |
| 84 | // Don't execute the task function, and set the |
| 85 | // delay to run it immediately whenever the |