예제 #1
0
파일: task_db.go 프로젝트: cloudfoundry/bbs
// The cell calls this when it has finished running the task (be it success or failure)
// stagerTaskBBS will retry this repeatedly if it gets a StoreTimeout error (up to N seconds?)
// This really really shouldn't fail.  If it does, blog about it and walk away. If it failed in a
// consistent way (i.e. key already exists), there's probably a flaw in our design.
func (db *ETCDDB) CompleteTask(logger lager.Logger, taskGuid, cellId string, failed bool, failureReason, result string) (*models.Task, error) {
	logger = logger.WithData(lager.Data{"task_guid": taskGuid, "cell_id": cellId})

	logger.Info("starting")
	defer logger.Info("finished")

	task, index, err := db.taskByGuidWithIndex(logger, taskGuid)
	if err != nil {
		logger.Error("failed-getting-task", err)
		return nil, err
	}

	if task.State == models.Task_Running && task.CellId != cellId {
		err = models.NewRunningOnDifferentCellError(cellId, task.CellId)
		logger.Error("invalid-cell-id", err)
		return nil, err
	}

	if err = task.ValidateTransitionTo(models.Task_Completed); err != nil {
		logger.Error("invalid-state-transition", err)
		return nil, err
	}

	return task, db.completeTask(logger, task, index, failed, failureReason, result)
}
예제 #2
0
파일: task_db.go 프로젝트: cloudfoundry/bbs
func (db *SQLDB) CompleteTask(logger lager.Logger, taskGuid, cellID string, failed bool, failureReason, taskResult string) (*models.Task, error) {
	logger = logger.Session("complete-task", lager.Data{"task_guid": taskGuid, "cell_id": cellID})
	logger.Info("starting")
	defer logger.Info("complete")

	var task *models.Task

	err := db.transact(logger, func(logger lager.Logger, tx *sql.Tx) error {
		var err error
		task, err = db.fetchTaskForUpdate(logger, taskGuid, tx)
		if err != nil {
			logger.Error("failed-locking-task", err)
			return err
		}

		if task.CellId != cellID && task.State == models.Task_Running {
			logger.Error("failed-task-already-running-on-different-cell", err)
			return models.NewRunningOnDifferentCellError(cellID, task.CellId)
		}

		if err = task.ValidateTransitionTo(models.Task_Completed); err != nil {
			logger.Error("failed-to-transition-task-to-completed", err)
			return err
		}

		return db.completeTask(logger, task, failed, failureReason, taskResult, tx)
	})

	return task, err
}
예제 #3
0
			BeforeEach(func() {
				taskDef = model_helpers.NewValidTaskDefinition()
			})

			JustBeforeEach(func() {
				err := etcdDB.DesireTask(logger, taskDef, taskGuid, domain)
				Expect(err).NotTo(HaveOccurred())

				_, err = etcdDB.StartTask(logger, taskGuid, cellId)
				Expect(err).NotTo(HaveOccurred())
			})

			Context("when the cell id is not the same", func() {
				It("returns an error", func() {
					task, err := etcdDB.CompleteTask(logger, taskGuid, "another-cell", true, "another failure reason", "")
					Expect(err).To(Equal(models.NewRunningOnDifferentCellError("another-cell", cellId)))
					Expect(task).To(BeNil())
				})
			})

			Context("when the cell id is the same", func() {
				It("sets the Task in the completed state", func() {
					clock.IncrementBySeconds(1)

					returnedTask, err := etcdDB.CompleteTask(logger, taskGuid, cellId, true, "because i said so", "a result")
					Expect(err).NotTo(HaveOccurred())
					Expect(returnedTask.TaskGuid).To(Equal(taskGuid))

					tasks := filterByState(models.Task_Completed)

					task := tasks[0]