Example #1
0
File: rpc.go Project: 40a/dkron
func (r *RPCServer) ExecutionDone(execution Execution, reply *serf.NodeResponse) error {
	log.WithFields(logrus.Fields{
		"group": execution.Group,
		"job":   execution.JobName,
	}).Debug("rpc: Received execution done")

	// Save job status
	job, err := r.agent.store.GetJob(execution.JobName)
	if err != nil {
		if err == store.ErrKeyNotFound {
			log.Warning(ErrExecutionDoneForDeletedJob)
			return ErrExecutionDoneForDeletedJob
		}
		log.Fatal("rpc:", err)
		return err
	}

	// Save the new execution to store
	if _, err := r.agent.store.SetExecution(&execution); err != nil {
		return err
	}

	if execution.Success {
		job.LastSuccess = execution.FinishedAt
		job.SuccessCount = job.SuccessCount + 1
	} else {
		job.LastError = execution.FinishedAt
		job.ErrorCount = job.ErrorCount + 1
	}

	if err := r.agent.store.SetJob(job); err != nil {
		log.Fatal("rpc:", err)
	}

	exg, err := r.agent.store.GetExecutionGroup(&execution)
	if err != nil {
		log.WithFields(logrus.Fields{
			"group": execution.Group,
			"err":   err,
		}).Error("rpc: Error getting execution group.")

		return err
	}

	// Send notification
	Notification(r.agent.config, &execution, exg).Send()

	reply.From = r.agent.config.NodeName
	reply.Payload = []byte("saved")

	return nil
}
Example #2
0
func (rpcs *RPCServer) ExecutionDone(execution Execution, reply *serf.NodeResponse) error {
	log.WithFields(logrus.Fields{
		"group": execution.Group,
		"job":   execution.JobName,
	}).Debug("rpc: Received execution done")

	// Load the job from the store
	job, err := rpcs.agent.store.GetJob(execution.JobName)
	if err != nil {
		if err == store.ErrKeyNotFound {
			log.Warning(ErrExecutionDoneForDeletedJob)
			return ErrExecutionDoneForDeletedJob
		}
		log.Fatal("rpc:", err)
		return err
	}
	// Lock the job while editing
	if err = job.Lock(); err != nil {
		log.Fatal("rpc:", err)
	}

	// Get the defined output types for the job, and call them
	origExec := execution
	for k, v := range job.Processors {
		log.WithField("plugin", k).Debug("rpc: Processing execution with plugin")
		processor := rpcs.agent.ProcessorPlugins[k]
		e := processor.Process(&ExecutionProcessorArgs{Execution: origExec, Config: v})
		execution = e
	}

	// Save the execution to store
	if _, err := rpcs.agent.store.SetExecution(&execution); err != nil {
		return err
	}

	if execution.Success {
		job.LastSuccess = execution.FinishedAt
		job.SuccessCount++
	} else {
		job.LastError = execution.FinishedAt
		job.ErrorCount++
	}

	if err := rpcs.agent.store.SetJob(job); err != nil {
		log.Fatal("rpc:", err)
	}

	// Release the lock
	if err = job.Unlock(); err != nil {
		log.Fatal("rpc:", err)
	}

	reply.From = rpcs.agent.config.NodeName
	reply.Payload = []byte("saved")

	// If the execution failed, retry it until retries limit (default: don't retry)
	if !execution.Success && execution.Attempt < job.Retries+1 {
		execution.Attempt++

		log.WithFields(logrus.Fields{
			"attempt":   execution.Attempt,
			"execution": execution,
		}).Debug("Retrying execution")

		rpcs.agent.RunQuery(&execution)
		return nil
	}

	exg, err := rpcs.agent.store.GetExecutionGroup(&execution)
	if err != nil {
		log.WithError(err).WithField("group", execution.Group).Error("rpc: Error getting execution group.")
		return err
	}

	// Send notification
	Notification(rpcs.agent.config, &execution, exg, job).Send()

	// Jobs that have dependent jobs are a bit more expensive because we need to call the Status() method for every execution.
	// Check first if there's dependent jobs and then check for the job status to begin executiong dependent jobs on success.
	if len(job.DependentJobs) > 0 && job.Status() == Success {
		for _, djn := range job.DependentJobs {
			dj, err := rpcs.agent.store.GetJob(djn)
			if err != nil {
				return err
			}
			dj.Run()
		}
	}

	return nil
}