Source:
<code>private Map<SystemStreamPartition, TaskSideInputHandler> createSideInputHandlers(Clock clock) { Map<TaskName, Map<String, SideInputsProcessor>> taskSideInputProcessors = createSideInputProcessors(new StorageConfig(config), this.containerModel, this.taskInstanceMetrics); Map<SystemStreamPartition, TaskSideInputHandler> handlers = new HashMap<>(); if (this.hasSideInputs) { containerModel.getTasks().forEach((taskName, taskModel) -> { Map<String, StorageEngine> sideInputStores = getSideInputStores(taskName); Map<String, Set<SystemStreamPartition>> sideInputStoresToSSPs = new HashMap<>(); CountDownLatch taskCountDownLatch = new CountDownLatch(1); <START> this.sideInputTaskLatches.put(taskName, taskCountDownLatch); <END> for (String storeName : sideInputStores.keySet()) { Set<SystemStreamPartition> storeSSPs = this.taskSideInputStoreSSPs.get(taskName).get(storeName); sideInputStoresToSSPs.put(storeName, storeSSPs); } TaskSideInputHandler taskSideInputHandler = new TaskSideInputHandler(taskName, taskModel.getTaskMode(), loggedStoreBaseDirectory, sideInputStores, sideInputStoresToSSPs, taskSideInputProcessors.get(taskName), this.systemAdmins, this.streamMetadataCache, taskCountDownLatch, clock); sideInputStoresToSSPs.values().stream().flatMap(Set::stream).forEach(ssp -> { handlers.put(ssp, taskSideInputHandler); }); LOG.info("Created TaskSideInputHandler for task {}, sideInputStores and loggedStoreBaseDirectory {}", taskName, sideInputStores, loggedStoreBaseDirectory); }); } return handlers; }</code><technical_language>do need granular latches? latch size of number of side input tasks & check reaches 0 instead</technical_language>

Target:
private Map<SystemStreamPartition, TaskSideInputHandler> createSideInputHandlers(Clock clock) { Map<TaskName, Map<String, SideInputsProcessor>> taskSideInputProcessors = createSideInputProcessors(new StorageConfig(config), this.containerModel, this.taskInstanceMetrics); Map<SystemStreamPartition, TaskSideInputHandler> handlers = new HashMap<>(); if (this.hasSideInputs) { containerModel.getTasks().forEach((taskName, taskModel) -> { Map<String, StorageEngine> sideInputStores = getSideInputStores(taskName); Map<String, Set<SystemStreamPartition>> sideInputStoresToSSPs = new HashMap<>(); boolean taskHasSideInputs = false; for (String storeName : sideInputStores.keySet()) { Set<SystemStreamPartition> storeSSPs = this.taskSideInputStoreSSPs.get(taskName).get(storeName); taskHasSideInputs = taskHasSideInputs || !storeSSPs.isEmpty(); sideInputStoresToSSPs.put(storeName, storeSSPs); } if (taskHasSideInputs) { CountDownLatch taskCountDownLatch = new CountDownLatch(1); this.sideInputTaskLatches.put(taskName, taskCountDownLatch); TaskSideInputHandler taskSideInputHandler = new TaskSideInputHandler(taskName, taskModel.getTaskMode(), loggedStoreBaseDirectory, sideInputStores, sideInputStoresToSSPs, taskSideInputProcessors.get(taskName), this.systemAdmins, this.streamMetadataCache, taskCountDownLatch, clock); sideInputStoresToSSPs.values().stream().flatMap(Set::stream).forEach(ssp -> { handlers.put(ssp, taskSideInputHandler); }); LOG.info("Created TaskSideInputHandler for task {}, sideInputStores and loggedStoreBaseDirectory {}", taskName, sideInputStores, loggedStoreBaseDirectory); } }); } return handlers; }