// PersistTaskQueue saves the task queue to the database. // Returns an error if the db call returns an error. func (self *DBTaskQueuePersister) PersistTaskQueue(distro string, tasks []task.Task, taskDurations model.ProjectTaskDurations) ([]model.TaskQueueItem, error) { taskQueue := make([]model.TaskQueueItem, 0, len(tasks)) for _, t := range tasks { expectedTaskDuration := model.GetTaskExpectedDuration(t, taskDurations) taskQueue = append(taskQueue, model.TaskQueueItem{ Id: t.Id, DisplayName: t.DisplayName, BuildVariant: t.BuildVariant, RevisionOrderNumber: t.RevisionOrderNumber, Requester: t.Requester, Revision: t.Revision, Project: t.Project, ExpectedDuration: expectedTaskDuration, Priority: t.Priority, }) if err := t.SetExpectedDuration(expectedTaskDuration); err != nil { evergreen.Logger.Errorf(slogger.ERROR, "Error updating projected task "+ "duration for %v: %v", t.Id, err) } } return taskQueue, model.UpdateTaskQueue(distro, taskQueue) }
// computeRunningTasksDuration returns the estimated time to completion of all // currently running tasks for a given distro given its hosts func computeRunningTasksDuration(existingDistroHosts []host.Host, taskDurations model.ProjectTaskDurations) (runningTasksDuration float64, err error) { runningTaskIds := []string{} for _, existingDistroHost := range existingDistroHosts { if existingDistroHost.RunningTask != "" { runningTaskIds = append(runningTaskIds, existingDistroHost.RunningTask) } } // if this distro's hosts are all free, return immediately if len(runningTaskIds) == 0 { return } runningTasksMap := make(map[string]model.Task) runningTasks, err := model.FindTasksByIds(runningTaskIds) if err != nil { return runningTasksDuration, err } // build a map of task id => task for _, runningTask := range runningTasks { runningTasksMap[runningTask.Id] = runningTask } // compute the total time to completion for running tasks for _, runningTaskId := range runningTaskIds { runningTask, ok := runningTasksMap[runningTaskId] if !ok { return runningTasksDuration, fmt.Errorf("Unable to find running "+ "task with _id %v", runningTaskId) } expectedDuration := model.GetTaskExpectedDuration(runningTask, taskDurations) elapsedTime := time.Now().Sub(runningTask.StartTime) if elapsedTime > expectedDuration { // probably an outlier; or an unknown data point continue } runningTasksDuration += expectedDuration.Seconds() - elapsedTime.Seconds() } return }
func (self *MockTaskQueuePersister) PersistTaskQueue(distro string, tasks []task.Task, projectTaskDuration model.ProjectTaskDurations) ([]model.TaskQueueItem, error) { taskQueue := make([]model.TaskQueueItem, 0, len(tasks)) for _, t := range tasks { expectedTaskDuration := model.GetTaskExpectedDuration(t, projectTaskDuration) if t.Priority < 0 { return taskQueue, fmt.Errorf("priority was %v but cannot be less than 0", t.Priority) } taskQueue = append(taskQueue, model.TaskQueueItem{ Id: t.Id, DisplayName: t.DisplayName, BuildVariant: t.BuildVariant, RevisionOrderNumber: t.RevisionOrderNumber, Requester: t.Requester, Revision: t.Revision, Project: t.Project, ExpectedDuration: expectedTaskDuration, Priority: t.Priority, }) } return taskQueue, nil }