Example #1
0
func (s *scheduler) createTask(sch schedule.Schedule, wfMap *wmap.WorkflowMap, startOnCreate bool, source string, opts ...core.TaskOption) (core.Task, core.TaskErrors) {
	logger := schedulerLogger.WithFields(log.Fields{
		"_block":          "create-task",
		"source":          source,
		"start-on-create": startOnCreate,
	})
	// Create a container for task errors
	te := &taskErrors{
		errs: make([]serror.SnapError, 0),
	}

	// Return error if we are not started.
	if s.state != schedulerStarted {
		te.errs = append(te.errs, serror.New(ErrSchedulerNotStarted))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error(ErrSchedulerNotStarted.Error())
		return nil, te
	}

	// Ensure the schedule is valid at this point and time.
	if err := sch.Validate(); err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("schedule passed not valid")
		return nil, te
	}

	// Generate a workflow from the workflow map
	wf, err := wmapToWorkflow(wfMap)
	if err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("Unable to generate workflow from workflow map")
		return nil, te
	}

	// Create the task object
	task, err := newTask(sch, wf, s.workManager, s.metricManager, s.eventManager, opts...)
	if err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("Unable to create task")
		return nil, te
	}

	// Group dependencies by the node they live on
	// and validate them.
	depGroups := getWorkflowPlugins(wf.processNodes, wf.publishNodes, wf.metrics)
	for k, group := range depGroups {
		manager, err := task.RemoteManagers.Get(k)
		if err != nil {
			te.errs = append(te.errs, serror.New(err))
			return nil, te
		}
		var errs []serror.SnapError
		errs = manager.ValidateDeps(group.requestedMetrics, group.subscribedPlugins, wf.configTree)

		if len(errs) > 0 {
			te.errs = append(te.errs, errs...)
			return nil, te
		}
	}

	// Add task to taskCollection
	if err := s.tasks.add(task); err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("errors during task creation")
		return nil, te
	}

	logger.WithFields(log.Fields{
		"task-id":    task.ID(),
		"task-state": task.State(),
	}).Info("task created")

	event := &scheduler_event.TaskCreatedEvent{
		TaskID:        task.id,
		StartOnCreate: startOnCreate,
		Source:        source,
	}
	defer s.eventManager.Emit(event)

	if startOnCreate {
		logger.WithFields(log.Fields{
			"task-id": task.ID(),
			"source":  source,
		}).Info("starting task on creation")

		errs := s.StartTask(task.id)
		if errs != nil {
			te.errs = append(te.errs, errs...)
		}
	}

	return task, te
}
Example #2
0
func (s *scheduler) createTask(sch schedule.Schedule, wfMap *wmap.WorkflowMap, startOnCreate bool, source string, opts ...core.TaskOption) (core.Task, core.TaskErrors) {
	logger := schedulerLogger.WithFields(log.Fields{
		"_block": "create-task",
		"source": source,
	})
	// Create a container for task errors
	te := &taskErrors{
		errs: make([]serror.SnapError, 0),
	}

	// Return error if we are not started.
	if s.state != schedulerStarted {
		te.errs = append(te.errs, serror.New(ErrSchedulerNotStarted))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("scheduler not started")
		return nil, te
	}

	// Ensure the schedule is valid at this point and time.
	if err := sch.Validate(); err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("schedule passed not valid")
		return nil, te
	}

	// Generate a workflow from the workflow map
	wf, err := wmapToWorkflow(wfMap)
	if err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error(ErrSchedulerNotStarted.Error())
		return nil, te
	}

	// validate plugins and metrics

	mts, plugins := s.gatherMetricsAndPlugins(wf)
	errs := s.metricManager.ValidateDeps(mts, plugins)
	if len(errs) > 0 {
		te.errs = append(te.errs, errs...)
		return nil, te
	}

	// Bind plugin content type selections in workflow
	err = wf.BindPluginContentTypes(s.metricManager)
	if err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("unable to bind plugin content types")
		return nil, te
	}

	// Create the task object
	task := newTask(sch, wf, s.workManager, s.metricManager, s.eventManager, opts...)

	// Add task to taskCollection
	if err := s.tasks.add(task); err != nil {
		te.errs = append(te.errs, serror.New(err))
		f := buildErrorsLog(te.Errors(), logger)
		f.Error("errors during task creation")
		return nil, te
	}

	logger.WithFields(log.Fields{
		"task-id":    task.ID(),
		"task-state": task.State(),
	}).Info("task created")

	event := &scheduler_event.TaskCreatedEvent{
		TaskID:        task.id,
		StartOnCreate: startOnCreate,
		Source:        source,
	}
	defer s.eventManager.Emit(event)

	if startOnCreate {
		logger.WithFields(log.Fields{
			"task-id": task.ID(),
			"source":  source,
		}).Info("starting task on creation")

		errs := s.StartTask(task.id)
		if errs != nil {
			te.errs = append(te.errs, errs...)
		}
	}

	return task, te
}