import java.util.ArrayList;
import java.util.List;

/** Bulkhead + fallback: beban berlebih dialihkan, tidak menumpuk di dependensi lambat. */
public class BulkheadFallback {

    /** Gerbang pembatas: paling banyak `kapasitas` pemanggil menghuni dependensi. */
    static class Bulkhead {
        private final int kapasitas;
        private int penghuni = 0;

        Bulkhead(int kapasitas) {
            this.kapasitas = kapasitas;
        }

        boolean cobaMasuk() {
            if (penghuni < kapasitas) {
                penghuni++;
                return true;
            }
            return false;
        }

        void keluar() {
            penghuni--;
        }

        int penghuni() {
            return penghuni;
        }
    }

    public static void main(String[] args) {
        // Lima permintaan tiba hampir bersamaan (satu gelombang)
        List<String> gelombang = List.of(
                "pesanan-1001", "pesanan-1002", "pesanan-1003",
                "pesanan-1004", "pesanan-1005");

        System.out.println("== TANPA BULKHEAD: semua menumpuk di dependensi lambat ==");
        System.out.println("menghuni svc-pembayaran : " + gelombang.size() + " pesanan");
        System.out.println("langkah kerja tersumbat : " + (gelombang.size() * 2));

        System.out.println();
        System.out.println("== DENGAN BULKHEAD (kapasitas 2) + FALLBACK ==");
        Bulkhead gerbang = new Bulkhead(2);

        List<String> diproses = new ArrayList<>();
        List<String> dialihkan = new ArrayList<>();
        for (String p : gelombang) {
            if (gerbang.cobaMasuk()) {
                diproses.add(p);
            } else {
                dialihkan.add(p); // load shedding: ditolak cepat, dialihkan ke fallback
            }
        }

        System.out.println("diproses svc-pembayaran : " + diproses);
        System.out.println("dialihkan ke fallback   : " + dialihkan + " (kwitansi cache)");
        System.out.println("penghuni gerbang        : " + gerbang.penghuni());

        // Dua pesanan selesai; slot terbuka untuk gelombang berikutnya
        gerbang.keluar();
        gerbang.keluar();
        System.out.println("setelah 2 selesai       : penghuni = " + gerbang.penghuni()
                + ", slot kembali tersedia");
    }
}
