github.com/kontera-technologies/go-supervisor/v2@v2.1.0/process-options.go (about)

     1  package supervisor
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"syscall"
     7  	"time"
     8  )
     9  
    10  type ProcessOptions struct {
    11  	// If Name contains no path separators, Command uses LookPath to
    12  	// resolve Name to a complete path if possible. Otherwise it uses Name
    13  	// directly as Path.
    14  	Name string
    15  
    16  	// The returned Cmd's Args field is constructed from the command name
    17  	// followed by the elements of arg, so arg should not include the
    18  	// command name itself. For example, Command("echo", "hello").
    19  	// Args[0] is always name, not the possibly resolved Path.
    20  	Args []string
    21  
    22  	// Env specifies the environment of the process.
    23  	// Each entry is of the form "key=value".
    24  	// If Env is nil, the new process uses the current process's
    25  	// environment.
    26  	// If Env contains duplicate environment keys, only the last
    27  	// value in the slice for each duplicate key is used.
    28  	Env []string
    29  
    30  	// When InheritEnv is true, os.Environ() will be prepended to Env.
    31  	InheritEnv bool
    32  
    33  	// Dir specifies the working directory of the command.
    34  	// If Dir is the empty string, Run runs the command in the
    35  	// calling process's current directory.
    36  	Dir string
    37  
    38  	// ExtraFiles specifies additional open files to be inherited by the
    39  	// new process. It does not include standard input, standard output, or
    40  	// standard error. If non-nil, entry i becomes file descriptor 3+i.
    41  	//
    42  	// ExtraFiles is not supported on Windows.
    43  	ExtraFiles []*os.File
    44  
    45  	// SysProcAttr holds optional, operating system-specific attributes.
    46  	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
    47  	SysProcAttr *syscall.SysProcAttr
    48  
    49  	In  chan []byte
    50  	Out chan *interface{}
    51  	Err chan *interface{}
    52  
    53  	EventNotifier chan Event
    54  
    55  	Id string
    56  
    57  	// Debug - when this flag is set to true, events will be logged to the default go logger.
    58  	Debug bool
    59  
    60  	OutputParser func(fromR io.Reader, bufferSize int) ProduceFn
    61  	ErrorParser  func(fromR io.Reader, bufferSize int) ProduceFn
    62  
    63  	// MaxSpawns is the maximum number of times that a process can be spawned
    64  	// Set to -1, for an unlimited amount of times.
    65  	// Will use defaultMaxSpawns when set to 0.
    66  	MaxSpawns int
    67  
    68  	// MaxSpawnAttempts is the maximum number of spawns attempts for a process.
    69  	// Set to -1, for an unlimited amount of attempts.
    70  	// Will use defaultMaxSpawnAttempts when set to 0.
    71  	MaxSpawnAttempts int
    72  
    73  	// MaxSpawnBackOff is the maximum duration that we will wait between spawn attempts.
    74  	// Will use defaultMaxSpawnBackOff when set to 0.
    75  	MaxSpawnBackOff time.Duration
    76  
    77  	// MaxRespawnBackOff is the maximum duration that we will wait between respawn attempts.
    78  	// Will use defaultMaxRespawnBackOff when set to 0.
    79  	MaxRespawnBackOff time.Duration
    80  
    81  	// MaxInterruptAttempts is the maximum number of times that we will try to interrupt the process when closed, before
    82  	// terminating and/or killing it.
    83  	// Set to -1, to never send the interrupt signal.
    84  	// Will use defaultMaxInterruptAttempts when set to 0.
    85  	MaxInterruptAttempts int
    86  
    87  	// MaxTerminateAttempts is the maximum number of times that we will try to terminate the process when closed, before
    88  	// killing it.
    89  	// Set to -1, to never send the terminate signal.
    90  	// Will use defaultMaxTerminateAttempts when set to 0.
    91  	MaxTerminateAttempts int
    92  
    93  	// NotifyEventTimeout is the amount of time that the process will BLOCK while trying to send an event.
    94  	NotifyEventTimeout time.Duration
    95  
    96  	// ParserBufferSize is the size of the buffer to be used by the OutputParser and ErrorParser.
    97  	// Will use defaultParserBufferSize when set to 0.
    98  	ParserBufferSize int
    99  
   100  	// IdleTimeout is the duration that the process can remain idle (no output) before we terminate the process.
   101  	// Set to -1, for an unlimited idle timeout (not recommended)
   102  	// Will use defaultIdleTimeout when set to 0.
   103  	IdleTimeout time.Duration
   104  
   105  	// TerminationGraceTimeout is the duration of time that the supervisor will wait after sending interrupt/terminate
   106  	// signals, before checking if the process is still alive.
   107  	// Will use defaultTerminationGraceTimeout when set to 0.
   108  	TerminationGraceTimeout time.Duration
   109  
   110  	// EventTimeFormat is the time format used when events are marshaled to string.
   111  	// Will use defaultEventTimeFormat when set to "".
   112  	EventTimeFormat string
   113  
   114  	// RunTimeout is the duration that the process can run before we terminate the process.
   115  	// Set to <= 0, for an unlimited run timeout
   116  	// Will use defaultRunTimeout when set to 0.
   117  	RunTimeout time.Duration
   118  }
   119  
   120  // init initializes the opts structure with default and required options.
   121  func initProcessOptions(opts ProcessOptions) *ProcessOptions {
   122  	if opts.SysProcAttr == nil {
   123  		opts.SysProcAttr = &syscall.SysProcAttr{}
   124  	} else {
   125  		opts.SysProcAttr = deepCloneSysProcAttr(*opts.SysProcAttr)
   126  	}
   127  
   128  	// Start a new process group for the spawned process.
   129  	opts.SysProcAttr.Setpgid = true
   130  
   131  	if opts.InheritEnv {
   132  		opts.Env = append(os.Environ(), opts.Env...)
   133  	}
   134  
   135  	if opts.MaxSpawns == 0 {
   136  		opts.MaxSpawns = defaultMaxSpawns
   137  	}
   138  	if opts.MaxSpawnAttempts == 0 {
   139  		opts.MaxSpawnAttempts = defaultMaxSpawnAttempts
   140  	}
   141  	if opts.MaxSpawnBackOff == 0 {
   142  		opts.MaxSpawnBackOff = defaultMaxSpawnBackOff
   143  	}
   144  	if opts.MaxRespawnBackOff == 0 {
   145  		opts.MaxRespawnBackOff = defaultMaxRespawnBackOff
   146  	}
   147  	if opts.MaxInterruptAttempts == 0 {
   148  		opts.MaxInterruptAttempts = defaultMaxInterruptAttempts
   149  	}
   150  	if opts.MaxTerminateAttempts == 0 {
   151  		opts.MaxTerminateAttempts = defaultMaxTerminateAttempts
   152  	}
   153  	if opts.NotifyEventTimeout == 0 {
   154  		opts.NotifyEventTimeout = defaultNotifyEventTimeout
   155  	}
   156  	if opts.ParserBufferSize == 0 {
   157  		opts.ParserBufferSize = defaultParserBufferSize
   158  	}
   159  	if opts.IdleTimeout == 0 {
   160  		opts.IdleTimeout = defaultIdleTimeout
   161  	}
   162  	if opts.IdleTimeout < 0 {
   163  		opts.IdleTimeout = time.Duration(maxDuration)
   164  	}
   165  	if opts.TerminationGraceTimeout == 0 {
   166  		opts.TerminationGraceTimeout = defaultTerminationGraceTimeout
   167  	}
   168  	if opts.EventTimeFormat == "" {
   169  		opts.EventTimeFormat = defaultEventTimeFormat
   170  	}
   171  	if opts.RunTimeout <= 0 {
   172  		opts.RunTimeout = defaultRunTimeout
   173  	}
   174  	if opts.In == nil {
   175  		opts.In = make(chan []byte)
   176  	}
   177  	if opts.Out == nil {
   178  		opts.Out = make(chan *interface{})
   179  	}
   180  	if opts.Err == nil {
   181  		opts.Err = make(chan *interface{})
   182  	}
   183  
   184  	return &opts
   185  }
   186  
   187  // deepCloneSysProcAttr is a helper function that deep-copies the syscall.SysProcAttr struct and returns a reference to the
   188  // new struct.
   189  func deepCloneSysProcAttr(x syscall.SysProcAttr) *syscall.SysProcAttr {
   190  	if x.Credential != nil {
   191  		y := *x.Credential
   192  		x.Credential = &y
   193  	}
   194  	return &x
   195  }