// AcceptTask attempts to queue a backupTask for delivery to the sessionQueue's
// tower. The session will only be accepted if the queue is not already
// exhausted and the task is successfully bound to the ClientSession.
493236
func (q *sessionQueue) AcceptTask(task *backupTask) (reserveStatus, bool) {
	q.queueCond.L.Lock()

	// Examine the current reserve status of the session queue.
	curStatus := q.reserveStatus()
	switch curStatus {

	// The session queue is exhausted, and cannot accept the task because it
	// is full. Reject the task such that it can be tried against a
	// different session.
	case reserveExhausted:
		q.queueCond.L.Unlock()
		return curStatus, false

	// The session queue is not exhausted. Compute the sweep and reward
	// outputs as a function of the session parameters. If the outputs are
	// dusty or uneconomical to backup, the task is rejected and will not be
	// tried again.
	//
	// TODO(conner): queue backups and retry with different session params.
	case reserveAvailable:
		err := task.bindSession(q.cfg.ClientSession)
		if err != nil {
			q.queueCond.L.Unlock()
			log.Debugf("SessionQueue %s rejected backup chanid=%s "+
				"commit-height=%d: %v", q.ID(), task.id.ChanID,
				task.id.CommitHeight, err)
			return curStatus, false
		}
	}

	// The sweep and reward outputs satisfy the session's policy, queue the
	// task for final signing and delivery.
	q.pendingQueue.PushBack(task)

	// Finally, compute the session's *new* reserve status. This will be
	// used by the client to determine if it can continue using this session
	// queue, or if it should negotiate a new one.
	newStatus := q.reserveStatus()
	q.queueCond.L.Unlock()

	q.queueCond.Signal()

	return newStatus, true
}
621192
func (sq *servingQueue) addTask(task *servingTask) {
	if sq.best == nil {
		sq.best = task
	} else if task.priority > sq.best.priority {
		sq.queue.Push(sq.best, sq.best.priority)
		sq.best = task
		return
	} else {
		sq.queue.Push(task, task.priority)
	}
}
1308051
func (s *session) sendTaskStatus(ctx context.Context, taskID string, taskStatus *api.TaskStatus) error {
	client := api.NewDispatcherClient(s.conn.ClientConn)
	if _, err := client.UpdateTaskStatus(ctx, &api.UpdateTaskStatusRequest{
		SessionID: s.sessionID,
		Updates: []*api.UpdateTaskStatusRequest_TaskStatusUpdate{
			{
				TaskID: taskID,
				Status: taskStatus,
			},
		},
	}); err != nil {
		// TODO(stevvooe): Dispatcher should not return this error. Status
		// reports for unknown tasks should be ignored.
		st, _ := status.FromError(err)
		if st.Code() == codes.NotFound {
			return errTaskUnknown
		}

		return err
	}

	return nil
}
239831
func (d *DeploymentRequest) GetTask() string {
	if d == nil || d.Task == nil {
		return ""
	}
	return *d.Task
}
189751
func (b *Builder) setTask(task *structs.Task) *Builder {
	b.taskName = task.Name
	b.envvars = make(map[string]string, len(task.Env))
	for k, v := range task.Env {
		b.envvars[k] = v
	}

	// COMPAT(0.11): Remove in 0.11
	if task.Resources == nil {
		b.memLimit = 0
		b.cpuLimit = 0
	} else {
		b.memLimit = int64(task.Resources.MemoryMB)
		b.cpuLimit = int64(task.Resources.CPU)
	}
	return b
}
1204416
func ValidateTask(task interface{}) error {
	v := reflect.ValueOf(task)
	t := v.Type()

	// Task must be a function
	if t.Kind() != reflect.Func {
		return ErrTaskMustBeFunc
	}

	// Task must return at least a single value
	if t.NumOut() < 1 {
		return ErrTaskReturnsNoValue
	}

	// Last return value must be error
	lastReturnType := t.Out(t.NumOut() - 1)
	errorInterface := reflect.TypeOf((*error)(nil)).Elem()
	if !lastReturnType.Implements(errorInterface) {
		return ErrLastReturnValueMustBeError
	}

	return nil
}
1206084
func (m TaskManager) AbortTask(c context.Context, ctl task.Controller) error {
	// This can happen if the invocation is aborted before it has even started.
	// We don't have buildbucket build ID yet to cancel.
	//
	// There's a high chance that LaunchTask is executing concurrently somewhere.
	// We let it finish peacefully, by not touching the invocation state at all
	// and failing with a transient error instead. This avoids a collision on
	// State modification. When such collision happens, results of LaunchTask
	// (including a fresh build ID) are discarded (as the engine is unable to
	// "merge" conflicting mutations from two different state transitions). This
	// is really bad, since this process produces orphaned Buildbucket builds.
	//
	// So we pick a lesser evil and make AbortTask fail transiently while
	// invocation is starting.
	if status := ctl.State().Status; status.Initial() {
		return errors.Reason("can't abort Buildbucket invocation in state %q", status).Tag(transient.Tag).Err()
	}

	// Grab build ID from the blob generated in LaunchTask.
	taskData, err := readTaskData(ctl)
	if err != nil {
		ctl.State().Status = task.StatusFailed
		return err
	}

	// Ask Buildbucket to kill this build.
	return utils.WrapAPIError(m.withBuildbucket(c, ctl, func(c context.Context, bb *bbv1.Service) error {
		_, err := bb.Cancel(taskData.BuildID, &bbv1.ApiCancelRequestBodyMessage{}).Context(c).Do()
		return err
	}))
}
1248431
func (c oauthClient) DeleteTask(task wl.Task) error {
	url := fmt.Sprintf(
		"%s/tasks/%d?revision=%d",
		c.apiURL,
		task.ID,
		task.Revision,
	)

	req, err := c.newDeleteRequest(url)
	if err != nil {
		return err
	}

	resp, err := c.do(req)
	if err != nil {
		return err
	}

	if resp.StatusCode != http.StatusNoContent {
		return fmt.Errorf("Unexpected response code %d - expected %d", resp.StatusCode, http.StatusNoContent)
	}

	return nil
}
236873
func (g *Orchestrator) FixTask(ctx context.Context, batch *store.Batch, t *api.Task) {
	if _, exists := g.globalServices[t.ServiceID]; !exists {
		return
	}
	// if a task's DesiredState has past running, the task has been processed
	if t.DesiredState > api.TaskStateRunning {
		return
	}

	var node *api.Node
	if t.NodeID != "" {
		node = g.nodes[t.NodeID]
	}
	// if the node no longer valid, remove the task
	if t.NodeID == "" || orchestrator.InvalidNode(node) {
		g.shutdownTask(ctx, batch, t)
		return
	}

	// restart a task if it fails
	if t.Status.State > api.TaskStateRunning {
		g.restartTasks[t.ID] = struct{}{}
	}
}
1028681
func ValidateTask(resources *api.Resources) error {
	for _, v := range resources.Generic {
		if v.GetDiscreteResourceSpec() != nil {
			continue
		}

		return fmt.Errorf("invalid argument for resource %s", Kind(v))
	}

	return nil
}
980505
func WriteTask(
	ctx types.Context,
	config gofig.Config,
	w http.ResponseWriter,
	store types.Store,
	task *types.Task,
	okStatus int) error {

	if store.GetBool("async") {
		WriteJSON(w, http.StatusAccepted, task)
		return nil
	}

	exeTimeoutDur, err := time.ParseDuration(
		config.GetString(types.ConfigServerTasksExeTimeout))
	if err != nil {
		exeTimeoutDur = time.Duration(time.Second * 60)
	}
	exeTimeout := time.NewTimer(exeTimeoutDur)

	select {
	case <-services.TaskWaitC(ctx, task.ID):
		if task.Error != nil {
			return task.Error
		}
		WriteJSON(w, okStatus, task.Result)
	case <-exeTimeout.C:
		WriteJSON(w, http.StatusRequestTimeout, task)
	}

	return nil
}
959715
func (b *Broker) nextTask(queue string) (result []byte, err error) {
	conn := b.open()
	defer conn.Close()

	items, err := redis.ByteSlices(conn.Do("BLPOP", queue, 1000))
	if err != nil {
		return []byte{}, err
	}

	// items[0] - the name of the key where an element was popped
	// items[1] - the value of the popped element
	if len(items) != 2 {
		return []byte{}, redis.ErrNil
	}

	result = items[1]

	return result, nil
}
362605
func (s *StopTaskOutput) SetTask(v *Task) *StopTaskOutput {
	s.Task = v
	return s
}
16744
func (m TaskManager) LaunchTask(c context.Context, ctl task.Controller) error {
	cfg := ctl.Task().(*messages.NoopTask)

	sleepFor := time.Duration(cfg.SleepMs) * time.Millisecond
	if sleepFor == 0 {
		sleepFor = 20 * time.Second
	}
	ctl.DebugLog("Running noop task for %s", sleepFor)
	clock.Sleep(c, sleepFor)

	for i := int64(0); i < cfg.TriggersCount; i++ {
		ctl.EmitTrigger(c, &internal.Trigger{
			Id:      fmt.Sprintf("noop:%d:%d", ctl.InvocationID(), i),
			Payload: &internal.Trigger_Noop{Noop: &api.NoopTrigger{}},
		})
	}

	ctl.State().Status = task.StatusSucceeded
	return nil
}
644584
func NewBackgroundTask(g *libkb.GlobalContext, args *BackgroundTaskArgs) *BackgroundTask {
	return &BackgroundTask{
		Contextified: libkb.NewContextified(g),
		args:         args,
		shutdownFunc: nil,
	}
}
1220733
func (s *Session) AcceptStream() (*Stream, error) {
	var deadline <-chan time.Time
	if d, ok := s.deadline.Load().(time.Time); ok && !d.IsZero() {
		timer := time.NewTimer(time.Until(d))
		defer timer.Stop()
		deadline = timer.C
	}
	select {
	case stream := <-s.chAccepts:
		return stream, nil
	case <-deadline:
		return nil, errTimeout
	case <-s.die:
		return nil, errors.New(errBrokenPipe)
	}
}
68469
func (s *ModifyReplicationTaskOutput) SetReplicationTask(v *ReplicationTask) *ModifyReplicationTaskOutput {
	s.ReplicationTask = v
	return s
}