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 }