001package com.mrivanplays.process; 002 003import java.util.Map; 004import java.util.concurrent.ConcurrentHashMap; 005import java.util.concurrent.CountDownLatch; 006import java.util.concurrent.Executor; 007import java.util.function.Consumer; 008 009/** 010 * Represents a completion of all the {@link ResultedProcess resulted processes} 011 * 012 * @param <T> result type parameter 013 * @author <a href="mailto:[email protected]">Ivan Pekov</a> 014 * @since 0.0.1 015 */ 016public final class ResultedProcessesCompletion<T> { 017 018 /** 019 * Called when all {@link ResultedProcess Proccesses} are done. 020 * <p><b>WARNING: THREAD BLOCKING METHOD.</b> 021 * 022 * @param callback a {@link Consumer} of the results 023 */ 024 public void whenDone(Consumer<Map<String, ProcessResult<T>>> callback) { 025 if (this.latch.getCount() == 0) { 026 callback.accept(this.resultMap); 027 return; 028 } 029 try { 030 this.latch.await(); 031 callback.accept(this.resultMap); 032 } catch (InterruptedException e) { 033 Thread.currentThread().interrupt(); 034 } 035 } 036 037 /** 038 * Called when all {@link ResultedProcess Processes} are done. The difference from {@link 039 * #whenDone(Consumer)} is that the waiting and the {@code callback} call is done asynchronously. 040 * 041 * @param callback a {@link Consumer} of the results. 042 * @see #whenDone(Consumer) 043 */ 044 public void whenDoneAsync(Consumer<Map<String, ProcessResult<T>>> callback) { 045 this.asyncExecutor.execute(() -> this.whenDone(callback)); 046 } 047 048 // ====================================== 049 050 private final CountDownLatch latch; 051 private final Executor asyncExecutor; 052 private Map<String, ProcessResult<T>> resultMap; 053 054 ResultedProcessesCompletion(int processCount, Executor asyncExecutor) { 055 this.latch = new CountDownLatch(processCount); 056 this.asyncExecutor = asyncExecutor; 057 this.resultMap = new ConcurrentHashMap<>(); 058 } 059 060 void countDown(String identifier, ProcessResult<T> result) { 061 this.resultMap.put(identifier, result); 062 this.latch.countDown(); 063 } 064}