func (r *Runner) finishTask(task kit.Task) { if task.IsComplete() { if !task.IsSuccess() { r.registry.Logger().Debugf("TaskRunner: Task %v failed after %v tries: %v", task.GetStrId(), task.GetTryCount(), task.GetError()) } else { secs := task.GetFinishedAt().Sub(*task.GetStartedAt()).Seconds() r.registry.Logger().Debugf("TaskRunner: Task %v completed successfully (%v secs)", task.GetStrId(), secs) } } else { r.Registry().Logger().Debugf("TaskRunner: Task %v(%v) failed, will retry: %v", task.GetStrId(), task.GetName(), task.GetError()) } if err := r.backend.Update(task); err != nil { r.registry.Logger().Errorf("TaskRunner: Could not update task: %v", err) } delete(r.activeTasks, task.GetStrId()) // Call onComplete handler if specified. spec := r.tasks[task.GetName()] onComplete := spec.GetOnCompleteHandler() if onComplete != nil { go onComplete(r.registry, task) } }
func (s *Service) Queue(task kit.Task) apperror.Error { task.SetCreatedAt(time.Now()) if task.GetName() == "" { return apperror.New("task_name_empty", "Can't queue a task without a name") } if err := s.backend.Create(task); err != nil { return err } return nil }
func (r *Runner) runTask(task kit.Task) apperror.Error { spec := r.tasks[task.GetName()] if spec == nil { return apperror.New("unknown_task", fmt.Sprintf("The task %v was not registered with the TaskRunner", task.GetName())) } now := time.Now() task.SetStartedAt(&now) task.SetIsRunning(true) if err := r.backend.Update(task); err != nil { return err } r.activeTasks[task.GetStrId()] = task r.registry.Logger().Debugf("TaskRunner: running task %v (task %v, try %v) (%v tasks running)", task.GetStrId(), task.GetName(), task.GetTryCount()+1, len(r.activeTasks)) go func(task kit.Task) { result, err, canRetry := spec.GetHandler()(r.registry, task, r.progressChan) now := time.Now() task.SetFinishedAt(&now) task.SetTryCount(task.GetTryCount() + 1) task.SetIsRunning(false) if err != nil { task.SetError(err.Error()) if !canRetry || task.GetTryCount() >= spec.GetAllowedRetries() { task.SetIsComplete(true) } else { runAt := time.Now().Add(spec.GetRetryInterval()) task.SetRunAt(&runAt) } } else { task.SetIsComplete(true) task.SetIsSuccess(true) task.SetResult(result) } r.finishedChan <- task }(task) return nil }