import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class PolaTerstruktur {

    static String muat(String layanan, int milidetik) throws InterruptedException {
        Thread.sleep(milidetik); // penungguan I/O tiruan
        return layanan + ": siap";
    }

    public static void main(String[] args) throws Exception {
        try (ExecutorService eksekutor = Executors.newVirtualThreadPerTaskExecutor()) {
            // Fase 1 "join-all": induk menunggu seluruh anak tuntas,
            // lalu mengumpulkan hasil atau kegagalan masing-masing.
            Future<String> katalog = eksekutor.submit(() -> muat("katalog", 40));
            Future<String> persediaan = eksekutor.submit(() -> muat("persediaan", 20));
            Future<String> galat = eksekutor.submit(() -> {
                throw new IllegalStateException("layanan ulasan galat");
            });

            List<String> laporan = new ArrayList<>();
            for (Future<String> f : List.of(katalog, persediaan, galat)) {
                try {
                    laporan.add(f.get());
                } catch (ExecutionException e) {
                    laporan.add("GAGAL: " + e.getCause().getMessage());
                }
            }
            laporan.sort(Comparator.naturalOrder());
            laporan.forEach(System.out::println);

            // Fase 2 "shutdown-on-failure": anak lambat dibatalkan
            // begitu saudaranya gagal cepat.
            Future<String> lambat = eksekutor.submit(() -> muat("rekomendasi", 500));
            Future<String> cepatGagal = eksekutor.submit(() -> {
                throw new IllegalStateException("cek kuota galat");
            });
            try {
                cepatGagal.get();
            } catch (ExecutionException e) {
                boolean dibatalkan = lambat.cancel(true); // interupsi saudara
                System.out.println("pembatalan: " + dibatalkan);
            }
        } // close(): induk tidak melanjutkan sebelum seluruh anak berhenti
    }
}
