1919import org .apache .lucene .store .IOContext ;
2020import org .apache .lucene .store .IndexOutput ;
2121import org .apache .lucene .store .RateLimitedIndexOutput ;
22+ import org .elasticsearch .ElasticsearchException ;
2223import org .elasticsearch .common .logging .Loggers ;
2324import org .elasticsearch .common .settings .Setting ;
2425import org .elasticsearch .core .TimeValue ;
@@ -99,12 +100,20 @@ public void refreshConfig() {
99100 }
100101
101102 @ Override
102- public void merge (MergeSource mergeSource , MergeTrigger trigger ) throws IOException {
103+ public void merge (MergeSource mergeSource , MergeTrigger trigger ) {
103104 if (closed ) {
104105 // avoid pulling from the merge source when closing
105106 return ;
106107 }
107- MergePolicy .OneMerge merge = mergeSource .getNextMerge ();
108+ MergePolicy .OneMerge merge = null ;
109+ try {
110+ merge = mergeSource .getNextMerge ();
111+ } catch (IllegalStateException e ) {
112+ if (verbose ()) {
113+ message ("merge task poll failed, likely that index writer is failed" );
114+ }
115+ // ignore exception, we expect the IW failure to be logged elsewhere
116+ }
108117 if (merge != null ) {
109118 submitNewMergeTask (mergeSource , merge , trigger );
110119 }
@@ -145,10 +154,13 @@ protected void handleMergeException(Throwable t) {
145154 throw new MergePolicy .MergeException (t );
146155 }
147156
148- private void submitNewMergeTask (MergeSource mergeSource , MergePolicy .OneMerge merge , MergeTrigger mergeTrigger ) {
149- MergeTask mergeTask = newMergeTask (mergeSource , merge , mergeTrigger );
150- threadPoolMergeExecutorService .submitMergeTask (mergeTask );
151- checkMergeTaskThrottling ();
157+ private boolean submitNewMergeTask (MergeSource mergeSource , MergePolicy .OneMerge merge , MergeTrigger mergeTrigger ) {
158+ try {
159+ MergeTask mergeTask = newMergeTask (mergeSource , merge , mergeTrigger );
160+ return threadPoolMergeExecutorService .submitMergeTask (mergeTask );
161+ } finally {
162+ checkMergeTaskThrottling ();
163+ }
152164 }
153165
154166 private void checkMergeTaskThrottling () {
@@ -179,16 +191,15 @@ private MergeTask newMergeTask(MergeSource mergeSource, MergePolicy.OneMerge mer
179191 );
180192 }
181193
182- // synchronized so that {@code #currentlyRunningMergeTasks} and {@code #backloggedMergeTasks} are modified atomically
194+ // synchronized so that {@code #closed}, {@code # currentlyRunningMergeTasks} and {@code #backloggedMergeTasks} are modified atomically
183195 private synchronized boolean runNowOrBacklog (MergeTask mergeTask ) {
184196 assert mergeTask .isRunning () == false ;
185- assert mergeTask .isOnGoingMergeAborted () == false ;
186197 if (closed ) {
187- // Do not backlog tasks when closing the merge scheduler, instead abort them.
188- // Aborted task are not actually executed.
198+ // Do not backlog or execute tasks when closing the merge scheduler, instead abort them.
189199 mergeTask .abortOnGoingMerge ();
190- return true ;
191- } else if (currentlyRunningMergeTasks .size () < config .getMaxThreadCount ()) {
200+ throw new ElasticsearchException ("merge task aborted because scheduler is shutting down" );
201+ }
202+ if (currentlyRunningMergeTasks .size () < config .getMaxThreadCount ()) {
192203 boolean added = currentlyRunningMergeTasks .put (mergeTask .onGoingMerge .getMerge (), mergeTask ) == null ;
193204 assert added : "starting merge task [" + mergeTask + "] registered as already running" ;
194205 return true ;
@@ -225,7 +236,7 @@ private synchronized void enqueueBackloggedTasks() {
225236 if (backloggedMergeTask == null ) {
226237 break ;
227238 }
228- // no need to abort merge tasks now, they will be aborted when the scheduler tries to run them
239+ // no need to abort merge tasks now, they will be aborted on the spot when the scheduler gets to run them
229240 threadPoolMergeExecutorService .enqueueMergeTask (backloggedMergeTask );
230241 }
231242 }
@@ -307,7 +318,6 @@ public boolean isRunning() {
307318 @ Override
308319 public void run () {
309320 assert isRunning () == false ;
310- assert isOnGoingMergeAborted () == false ;
311321 assert ThreadPoolMergeScheduler .this .currentlyRunningMergeTasks .containsKey (onGoingMerge .getMerge ())
312322 : "runNowOrBacklog must be invoked before actually running the merge task" ;
313323 try {
@@ -360,21 +370,8 @@ public void run() {
360370 message (String .format (Locale .ROOT , "merge task %s end" , this ));
361371 }
362372 mergeDone (this );
363- if (ThreadPoolMergeScheduler .this .closed == false ) {
364- // kick-off next merge, if any
365- MergePolicy .OneMerge nextMerge = null ;
366- try {
367- nextMerge = mergeSource .getNextMerge ();
368- } catch (IllegalStateException e ) {
369- if (verbose ()) {
370- message ("merge task poll failed, likely that index writer is failed" );
371- }
372- // ignore exception, we expect the IW failure to be logged elsewhere
373- }
374- if (nextMerge != null ) {
375- submitNewMergeTask (mergeSource , nextMerge , MergeTrigger .MERGE_FINISHED );
376- }
377- }
373+ // kick-off next merge, if any
374+ merge (mergeSource , MergeTrigger .MERGE_FINISHED );
378375 }
379376 }
380377
@@ -388,13 +385,9 @@ void abortOnGoingMerge() {
388385 doneMergeTaskCount .incrementAndGet ();
389386 }
390387
391- boolean isOnGoingMergeAborted () {
392- return onGoingMerge .getMerge ().isAborted ();
393- }
394-
395388 @ Override
396389 public String toString () {
397- return name + (isOnGoingMergeAborted () ? " (aborted)" : "" );
390+ return name + (onGoingMerge . getMerge (). isAborted () ? " (aborted)" : "" );
398391 }
399392 }
400393
0 commit comments