func (r *RunParams) WaitWithCancel(cancel <-chan struct{}) (*ExecResponse, error) {
	// TODO: Remove this once we make Clock a required field
	_clock := r.Clock
	if _clock == nil {
		_clock = clock.WallClock
	}

	done := make(chan resultWithError, 1)
	go func() {
		defer close(done)
		waitResult, err := r.Wait()
		done <- resultWithError{waitResult, err}
	}()

	select {
	case resWithError := <-done:
		return resWithError.execResult, errors.Trace(resWithError.err)
	case <-cancel:
		logger.Debugf("attempting to kill process")
		err := r.KillProcess(r.ps.Process)
		if err != nil {
			logger.Debugf("kill returned: %s", err)
		}

		// After we issue a kill we expect the wait above to return within timeWaitForKill.
		// In case it doesn't we just go on and assume the process is stuck, but we don't block
		select {
		case resWithError := <-done:
			return resWithError.execResult, ErrCancelled
		case <-_clock.After(timeWaitForKill):
			return nil, errors.Errorf("tried to kill process %v, but timed out", r.ps.Process.Pid)
		}
	}
}
// WaitWithCancel waits until the process exits or until a signal is sent on the
// cancel channel. In case a signal is sent it first tries to kill the process and
// return ErrCancelled. If it fails at killing the process it will return anyway
// and report the problematic PID.
WaitWithCancel waits until the process exits or until a signal is sent on the
cancel channel. In case a signal is sent it first tries to kill the process and
return ErrCancelled. If it fails at killing the process it will return anyway
and report the problematic PID.
// WaitWithCancel waits until the process exits or until a signal is sent on the // cancel channel . In case a signal is sent it first tries to kill the process and // return ErrCancelled . If it fails at killing the process it will return anyway // and report the problematic PID .
func (r *RunParams) WaitWithCancel(cancel <-chan struct{}) (*ExecResponse, error) {
	_clock := r.Clock
	if _clock == nil {
		_clock = clock.WallClock
	}
	done := make(chan resultWithError, 1)
	go func() {
		defer close(done)
		waitResult, err := r.Wait()
		done <- resultWithError{waitResult, err}
	}()
	select {
	case resWithError := <-done:
		return resWithError.execResult, errors.Trace(resWithError.err)
	case <-cancel:
		logger.Debugf("attempting to kill process")
		err := r.KillProcess(r.ps.Process)
		if err != nil {
			logger.Debugf("kill returned: %s", err)
		}
		select {
		case resWithError := <-done:
			return resWithError.execResult, ErrCancelled
		case <-_clock.After(timeWaitForKill):
			return nil, errors.Errorf("tried to kill process %v, but timed out", r.ps.Process.Pid)
		}
	}
}
func ( r * RunParams ) WaitWithCancel ( cancel <- chan struct { } ) ( * ExecResponse , error ) { _clock := r . Clock if _clock == nil { _clock = clock . WallClock } done := make ( chan resultWithError , 1 ) go func ( ) { defer close ( done ) waitResult , err := r . Wait ( ) done <- resultWithError { waitResult , err } } ( ) select { case resWithError := <- done : return resWithError . execResult , errors . Trace ( resWithError . err ) case <- cancel : logger . Debugf ( " " ) err := r . KillProcess ( r . ps . Process ) if err != nil { logger . Debugf ( " " , err ) } select { case resWithError := <- done : return resWithError . execResult , ErrCancelled case <- _clock . After ( timeWaitForKill ) : return nil , errors . Errorf ( " " , r . ps . Process . Pid ) } } }
WaitWithCancel waits until the process exits or until a signal is sent on the
cancel channel.
WaitWithCancel waits until the process exits or until a signal is sent on the cancel channel .
// TODO: Remove this once we make Clock a required field // After we issue a kill we expect the wait above to return within timeWaitForKill. // In case it doesn't we just go on and assume the process is stuck, but we don't block