github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/index/stallControl.go (about)

     1  package index
     2  
     3  import (
     4  	"sync"
     5  )
     6  
     7  /*
     8  Controls the health status of a DocumentsWriter sessions. This class
     9  used to block incoming index threads if flushing significantly slower
    10  than indexing to ensure the DocumentsWriter's healthiness. If
    11  flushing is significantly slower than indexing the net memory used
    12  within an IndexWriter session can increase very quickly and easily
    13  exceed the JVM's available memory.
    14  
    15  To prevent OOM errors and ensure IndexWriter's stability this class
    16  blocks incoming threads from indexing once 2 x number of available
    17  ThreadState(s) in DocumentsWriterPerThreadPool is exceeded. Once
    18  flushing catches up and number of flushing DWPT is equal of lower
    19  than the number of active ThreadState(s) threads are released and can
    20  continue indexing.
    21  */
    22  type DocumentsWriterStallControl struct {
    23  	sync.Locker
    24  	*sync.Cond
    25  
    26  	stalled    bool // volatile
    27  	numWaiting int
    28  	wasStalled bool // assert only
    29  }
    30  
    31  func newDocumentsWriterStallControl() *DocumentsWriterStallControl {
    32  	lock := &sync.Mutex{}
    33  	return &DocumentsWriterStallControl{
    34  		Locker: lock,
    35  		Cond:   sync.NewCond(lock),
    36  	}
    37  }
    38  
    39  /*
    40  Update the stalled flag status. This method will set the stalled flag
    41  to true iff the number of flushing DWPT is greater than the number of
    42  active DWPT. Otherwise it will reset the DWSC to healthy and release
    43  all threads waiting on waitIfStalled()
    44  */
    45  func (sc *DocumentsWriterStallControl) updateStalled(stalled bool) {
    46  	sc.Lock()
    47  	defer sc.Unlock()
    48  	sc.stalled = stalled
    49  	if stalled {
    50  		sc.wasStalled = true
    51  	}
    52  	sc.Signal()
    53  }
    54  
    55  /* Blocks if documents writing is currently in a stalled state. */
    56  func (sc *DocumentsWriterStallControl) waitIfStalled() {
    57  	sc.Lock()
    58  	defer sc.Unlock()
    59  	if sc.stalled { // react on the first wake up call!
    60  		// don't loop here, higher level logic will re-stall
    61  		assert(sc.incWaiters())
    62  		sc.Wait()
    63  		assert(sc.decWaiters())
    64  	}
    65  }
    66  
    67  func (sc *DocumentsWriterStallControl) anyStalledThreads() bool {
    68  	return sc.stalled
    69  }
    70  
    71  func (sc *DocumentsWriterStallControl) incWaiters() bool {
    72  	sc.numWaiting++
    73  	return sc.numWaiting > 0
    74  }
    75  
    76  func (sc *DocumentsWriterStallControl) decWaiters() bool {
    77  	sc.numWaiting--
    78  	return sc.numWaiting >= 0
    79  }