CopyOnReadDirectory extends FilterDirectory { @Override public void close() throws IOException { if (!closed.compareAndSet(false, true)){ return; } executor.execute(new Runnable() { @Override public void run() { try{ removeDeletedFiles(); } catch (IOException e) { log.warn( "[{}] Error occurred while removing deleted files from Local {}, Remote {}", indexPath, local, remote, e); } try { local.close(); remote.close(); } catch (IOException e) { log.warn( "[{}] Error occurred while closing directory ", indexPath, e); } } }); } CopyOnReadDirectory(IndexCopier indexCopier, Directory remote, Directory local, boolean prefetch,
                               String indexPath, Executor executor); @Override void deleteFile(String name); @Override IndexOutput createOutput(String name, IOContext context); @Override IndexInput openInput(String name, IOContext context); Directory getLocal(); @Override void close(); @Override String toString(); static final String DELETE_MARGIN_MILLIS_NAME; final long DELETE_MARGIN_MILLIS; }
@Test public void multipleCloseCalls() throws Exception{ AtomicInteger executionCount = new AtomicInteger(); Executor e = r -> {executionCount.incrementAndGet(); r.run();}; IndexCopier c = new IndexCopier(sameThreadExecutor(), temporaryFolder.newFolder(), true); Directory dir = new CopyOnReadDirectory(c, new RAMDirectory(), new RAMDirectory(), false, "foo", e); dir.close(); dir.close(); assertEquals(1, executionCount.get()); }