@Override
 public void flush(Flush flush) throws EngineException {
   if (indexWriter == null) {
     throw new EngineClosedException(shardId);
   }
   // check outside the lock as well so we can check without blocking on the write lock
   if (disableFlushCounter > 0) {
     throw new FlushNotAllowedEngineException(
         shardId, "Recovery is in progress, flush is not allowed");
   }
   rwl.writeLock().lock();
   try {
     if (indexWriter == null) {
       throw new EngineClosedException(shardId);
     }
     if (disableFlushCounter > 0) {
       throw new FlushNotAllowedEngineException(
           shardId, "Recovery is in progress, flush is not allowed");
     }
     if (flush.full()) {
       // disable refreshing, not dirty
       dirty = false;
       refreshMutex.set(true);
       try {
         // that's ok if the index writer failed and is in inconsistent state
         // we will get an exception on a dirty operation, and will cause the shard
         // to be allocated to a different node
         indexWriter.close();
         indexWriter = createWriter();
         AcquirableResource<ReaderSearcherHolder> current = nrtResource;
         nrtResource = buildNrtResource(indexWriter);
         current.markForClose();
         translog.newTranslog(newTransactionLogId());
       } catch (IOException e) {
         throw new FlushFailedEngineException(shardId, e);
       } finally {
         refreshMutex.set(false);
       }
     } else {
       try {
         indexWriter.commit();
         translog.newTranslog(newTransactionLogId());
       } catch (IOException e) {
         throw new FlushFailedEngineException(shardId, e);
       }
     }
   } finally {
     rwl.writeLock().unlock();
   }
   if (flush.refresh()) {
     refresh(new Refresh(false));
   }
 }
 @Override
 public Searcher searcher() throws EngineException {
   AcquirableResource<ReaderSearcherHolder> holder;
   for (; ; ) {
     holder = this.nrtResource;
     if (holder.acquire()) {
       break;
     }
     Thread.yield();
   }
   return new RobinSearchResult(holder);
 }
 @Override
 public void refresh(Refresh refresh) throws EngineException {
   // we obtain a read lock here, since we don't want a flush to happen while we are refreshing
   // since it flushes the index as well (though, in terms of concurrency, we are allowed to do it)
   rwl.readLock().lock();
   if (indexWriter == null) {
     throw new EngineClosedException(shardId);
   }
   try {
     // this engine always acts as if waitForOperations=true
     if (refreshMutex.compareAndSet(false, true)) {
       IndexWriter currentWriter = indexWriter;
       if (currentWriter == null) {
         throw new EngineClosedException(shardId);
       }
       try {
         if (dirty) {
           dirty = false;
           AcquirableResource<ReaderSearcherHolder> current = nrtResource;
           IndexReader newReader = current.resource().reader().reopen(true);
           if (newReader != current.resource().reader()) {
             IndexSearcher indexSearcher = new IndexSearcher(newReader);
             indexSearcher.setSimilarity(similarityService.defaultSearchSimilarity());
             nrtResource = newAcquirableResource(new ReaderSearcherHolder(indexSearcher));
             current.markForClose();
           }
         }
       } catch (AlreadyClosedException e) {
         // an index writer got replaced on us, ignore
       } catch (Exception e) {
         if (indexWriter == null) {
           throw new EngineClosedException(shardId);
         } else if (currentWriter != indexWriter) {
           // an index writer got replaced on us, ignore
         } else {
           throw new RefreshFailedEngineException(shardId, e);
         }
       } finally {
         refreshMutex.set(false);
       }
     }
   } finally {
     rwl.readLock().unlock();
   }
 }
 @Override
 public boolean release() throws ElasticSearchException {
   nrtHolder.release();
   return true;
 }
 @Override
 public IndexSearcher searcher() {
   return nrtHolder.resource().searcher();
 }
 @Override
 public IndexReader reader() {
   return nrtHolder.resource().reader();
 }