Skip to content

Commit

Permalink
modify task service to allow tasks to repeat ASAP
Browse files Browse the repository at this point in the history
Previously, when completing a task, an available time of nil would
cause the task to be marked as failed.

Now, when a task completes and has available time of nil, time.Now() is
substituted, which should cause the task to be run again ASAP.

In addition, if the available time is in the past, it is substituted
with time.Now(), so that it will run again ASAP.

This supports the care partner no communication check, which wants to
run 1x/second, but as that's not available with the task service (the
smallest interval is 5 seconds), setting the value to 1 second
intervals will run the task on each task service iteration.

BACK-2559
  • Loading branch information
ewollesen committed Feb 18, 2025
1 parent 8f3d3ab commit 7a55626
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 30 deletions.
29 changes: 2 additions & 27 deletions alerts/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ func (r *CarePartnerRunner) GetRunnerDurationMaximum() time.Duration {

func (r *CarePartnerRunner) Run(ctx context.Context, tsk *task.Task) {
r.logger.Info("care partner no communication check")
ctx = auth.NewContextWithServerSessionTokenProvider(ctx, r.authClient)
start := time.Now()
ctx = auth.NewContextWithServerSessionTokenProvider(ctx, r.authClient)
if err := r.evaluateLastComms(ctx); err != nil {
r.logger.WithError(err).Warn("running care partner no communication check")
}
r.scheduleNextRun(tsk, start)
tsk.RepeatAvailableAfter(time.Second - time.Since(start))
}

func (r *CarePartnerRunner) evaluateLastComms(ctx context.Context) error {
Expand Down Expand Up @@ -201,31 +201,6 @@ func (r *CarePartnerRunner) pushNotifications(ctx context.Context,
}
}

func (r *CarePartnerRunner) scheduleNextRun(tsk *task.Task, lastStart time.Time) {
// Ideally, we would start the next run 1 second after this run...
nextDesiredRun := lastStart.Add(time.Second)
now := time.Now()
if nextDesiredRun.Before(now) {
r.logger.Info("care partner is bumping nextDesiredRun")
// nextDesiredRun, when added to time.Now in tsk.RepeatAvailableAfter, must
// result in a time in the future or the task will be marked failed (and not run
// again).
//
// One workaround is to take a guess at how long it will take Run() to return
// and the task queue to evaluate the task's AvailableAfter time. Maybe the task
// queue could be re-worked to accept a value that indicates "as soon as
// possible"? Or if it accepted a time.Duration, then one could pass it
// time.Nanosecond to get closer to "ASAP", and then the Zero value might mean
// don't repeat. Or the Zero value could mean repeat ASAP. Or a negative value
// could mean repeat now. Whatever. It would prevent the task from being marked
// a failure for not being able to guess when the value would be read. Which
// wasn't its intent I'm sure, it just wasn't designed for tasks with the level
// of resolution and repetition expected for this purpose.
nextDesiredRun = now.Add(25 * time.Millisecond)
}
tsk.RepeatAvailableAfter(time.Until(nextDesiredRun))
}

// Pusher is a service-agnostic interface for sending push notifications.
type Pusher interface {
// Push a notification to a device.
Expand Down
7 changes: 5 additions & 2 deletions alerts/tasks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ import (

var _ = Describe("CarePartnerRunner", func() {
Describe("Run", func() {
It("schedules its next run", func() {
It("schedules its next run for 1 second", func() {
runner, test := newCarePartnerRunnerTest()

start := time.Now()
runner.Run(test.Ctx, test.Task)

Expect(test.Task.AvailableTime).ToNot(BeZero())
if Expect(test.Task.AvailableTime).ToNot(BeNil()) {
Expect(*test.Task.AvailableTime).To(BeTemporally("~", start.Add(time.Second)))
}
Expect(test.Task.DeadlineTime).To(BeNil())
Expect(test.Task.State).To(Equal(task.TaskStatePending))
})
Expand Down
5 changes: 4 additions & 1 deletion task/queue/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,10 @@ func (q *queue) completeTask(ctx context.Context, tsk *task.Task) {
func (q *queue) computeState(tsk *task.Task) {
switch tsk.State {
case task.TaskStatePending:
if tsk.AvailableTime == nil || time.Now().After(*tsk.AvailableTime) {
now := time.Now()
if tsk.AvailableTime == nil || tsk.AvailableTime.Before(now) {
tsk.AvailableTime = &now
} else if time.Now().After(*tsk.AvailableTime) {
tsk.AppendError(errors.New("pending task requires future available time"))
tsk.SetFailed()
}
Expand Down

0 comments on commit 7a55626

Please sign in to comment.