github.com/bigcommerce/nomad@v0.9.3-bc/client/allocrunner/taskrunner/lifecycle.go (about)

     1  package taskrunner
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/hashicorp/nomad/nomad/structs"
     7  )
     8  
     9  // Restart a task. Returns immediately if no task is running. Blocks until
    10  // existing task exits or passed-in context is canceled.
    11  func (tr *TaskRunner) Restart(ctx context.Context, event *structs.TaskEvent, failure bool) error {
    12  	tr.logger.Trace("Restart requested", "failure", failure)
    13  
    14  	// Grab the handle
    15  	handle := tr.getDriverHandle()
    16  
    17  	// Check it is running
    18  	if handle == nil {
    19  		return ErrTaskNotRunning
    20  	}
    21  
    22  	// Emit the event since it may take a long time to kill
    23  	tr.EmitEvent(event)
    24  
    25  	// Run the pre-kill hooks prior to restarting the task
    26  	tr.preKill()
    27  
    28  	// Tell the restart tracker that a restart triggered the exit
    29  	tr.restartTracker.SetRestartTriggered(failure)
    30  
    31  	// Kill the task using an exponential backoff in-case of failures.
    32  	if err := tr.killTask(handle); err != nil {
    33  		// We couldn't successfully destroy the resource created.
    34  		tr.logger.Error("failed to kill task. Resources may have been leaked", "error", err)
    35  	}
    36  
    37  	// Drain the wait channel or wait for the request context to be canceled
    38  	waitCh, err := handle.WaitCh(ctx)
    39  	if err != nil {
    40  		return err
    41  	}
    42  
    43  	select {
    44  	case <-waitCh:
    45  	case <-ctx.Done():
    46  	}
    47  	return nil
    48  }
    49  
    50  func (tr *TaskRunner) Signal(event *structs.TaskEvent, s string) error {
    51  	tr.logger.Trace("Signal requested", "signal", s)
    52  
    53  	// Grab the handle
    54  	handle := tr.getDriverHandle()
    55  
    56  	// Check it is running
    57  	if handle == nil {
    58  		return ErrTaskNotRunning
    59  	}
    60  
    61  	// Emit the event
    62  	tr.EmitEvent(event)
    63  
    64  	// Send the signal
    65  	return handle.Signal(s)
    66  }
    67  
    68  // Kill a task. Blocks until task exits or context is canceled. State is set to
    69  // dead.
    70  func (tr *TaskRunner) Kill(ctx context.Context, event *structs.TaskEvent) error {
    71  	tr.logger.Trace("Kill requested", "event_type", event.Type, "event_reason", event.KillReason)
    72  
    73  	// Cancel the task runner to break out of restart delay or the main run
    74  	// loop.
    75  	tr.killCtxCancel()
    76  
    77  	// Emit kill event
    78  	tr.EmitEvent(event)
    79  
    80  	select {
    81  	case <-tr.WaitCh():
    82  	case <-ctx.Done():
    83  		return ctx.Err()
    84  	}
    85  
    86  	return tr.getKillErr()
    87  }