github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/agent/comm/timeout.go (about)

     1  package comm
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  )
     7  
     8  // TimeoutWatcher tracks and handles command timeout within the agent.
     9  type TimeoutWatcher struct {
    10  	duration time.Duration
    11  	timer    *time.Timer
    12  	stop     <-chan struct{}
    13  	disabled bool
    14  
    15  	mutex sync.Mutex
    16  }
    17  
    18  func NewTimeoutWatcher(stopChan <-chan struct{}) *TimeoutWatcher {
    19  	// TODO: replace this with a context for cancellation, and be
    20  	// able to eliminate the constructor
    21  	return &TimeoutWatcher{stop: stopChan}
    22  }
    23  
    24  // SetDuration sets the duration after which a timeout is triggered.
    25  func (tw *TimeoutWatcher) SetDuration(duration time.Duration) {
    26  	tw.mutex.Lock()
    27  	defer tw.mutex.Unlock()
    28  
    29  	tw.duration = duration
    30  }
    31  
    32  // CheckIn resets the idle timer to zero.
    33  func (tw *TimeoutWatcher) CheckIn() {
    34  	tw.mutex.Lock()
    35  	defer tw.mutex.Unlock()
    36  
    37  	if tw.timer != nil && !tw.disabled {
    38  		tw.timer.Reset(tw.duration)
    39  	}
    40  }
    41  
    42  // NotifyTimeouts sends a signal on sigChan whenever the timeout threshold of
    43  // the current execution stage is reached.
    44  func (tw *TimeoutWatcher) NotifyTimeouts(sigChan chan<- Signal) {
    45  	go func() {
    46  		tw.mutex.Lock()
    47  		if tw.timer == nil {
    48  			if tw.duration <= 0 {
    49  				tw.mutex.Unlock()
    50  				panic("can't wait for timeouts with negative duration")
    51  			}
    52  			tw.timer = time.NewTimer(tw.duration)
    53  		}
    54  		tw.mutex.Unlock()
    55  
    56  		select {
    57  		case <-tw.timer.C:
    58  			// if execution reaches here, it's timed out.
    59  			// send the time out signal on sigChan
    60  			sigChan <- IdleTimeout
    61  			return
    62  		case <-tw.stop:
    63  			return
    64  		}
    65  	}()
    66  }