Source:
<code>void setup(final ExecutableFlow flow) throws ExecutorManagerException { final ProjectFileHandler projectFileHandler = null; File tempDir = null; try { final ProjectDirectoryMetadata project = new ProjectDirectoryMetadata( flow.getProjectId(), flow.getVersion()); final long flowPrepStartTime = System.currentTimeMillis(); tempDir = createTempDir(project); final long start = System.currentTimeMillis(); final boolean isDownloaded = downloadProjectIfNotExists(project, tempDir); log.info("Downloading zip file for project when preparing execution [execid {}] " + "completed in second(s)", project, flow.getExecutionId(), (System.currentTimeMillis() - start) / 1000); long criticalSectionStartTime = -1; File execDir = null; synchronized (this) { criticalSectionStartTime = System.currentTimeMillis(); if (!project.getInstalledDir().exists()) { if (isDownloaded && this.projectCacheCleaner.isPresent()) { this.projectCacheCleaner.get() <START> .deleteProjectDirsIfNecessary(project.getDirSizeInByte()); <END> } Files.move(tempDir.toPath(), project.getInstalledDir().toPath()); } execDir = setupExecutionDir(project.getInstalledDir(), flow); } final long flowPrepCompletionTime = System.currentTimeMillis(); log.info("Flow preparation completed in sec(s), out ot which sec(s) was spent inside " + "critical section. [execid: {}, path: {}]", (flowPrepCompletionTime - flowPrepStartTime) / 1000, (flowPrepCompletionTime - criticalSectionStartTime) / 1000, flow.getExecutionId(), execDir.getPath()); } catch (final Exception ex) { log.error("Error in preparing flow execution {}", flow.getExecutionId(), ex); throw new ExecutorManagerException(ex); } finally { if (projectFileHandler != null) { projectFileHandler.deleteLocalFile(); } FileIOUtils.deleteDirectory(tempDir); } }</code><technical_language>disk cleanup, takes ~1 hour (up 2 hours) remove ~1000 project directories. Removing 1 directory 3.6 seconds, if this scales</technical_language>

Target:
void setup(final ExecutableFlow flow) throws ExecutorManagerException { final ProjectFileHandler projectFileHandler = null; File tempDir = null; try { final ProjectDirectoryMetadata project = new ProjectDirectoryMetadata( flow.getProjectId(), flow.getVersion()); final long flowPrepStartTime = System.currentTimeMillis(); final long start = System.currentTimeMillis(); tempDir = downloadProjectIfNotExists(project); log.info("Downloading zip file for project when preparing execution [execid {}] " + "completed in second(s)", project, flow.getExecutionId(), (System.currentTimeMillis() - start) / 1000); long criticalSectionStartTime = -1; File execDir = null; synchronized (this) { criticalSectionStartTime = System.currentTimeMillis(); if (!project.getInstalledDir().exists() && tempDir != null) { if (this.projectCacheCleaner.isPresent()) { this.projectCacheCleaner.get() .deleteProjectDirsIfNecessary(project.getDirSizeInByte()); } Files.move(tempDir.toPath(), project.getInstalledDir().toPath()); } execDir = setupExecutionDir(project.getInstalledDir(), flow); } final long flowPrepCompletionTime = System.currentTimeMillis(); log.info("Flow preparation completed in sec(s), out ot which sec(s) was spent inside " + "critical section. [execid: {}, path: {}]", (flowPrepCompletionTime - flowPrepStartTime) / 1000, (flowPrepCompletionTime - criticalSectionStartTime) / 1000, flow.getExecutionId(), execDir.getPath()); } catch (final Exception ex) { FileIOUtils.deleteDirectorySilently(tempDir); log.error("Error in preparing flow execution {}", flow.getExecutionId(), ex); throw new ExecutorManagerException(ex); } finally { if (projectFileHandler != null) { projectFileHandler.deleteLocalFile(); } } }