---
title: 'Dayanıklılık ve Güvenilirlik'
source: 'https://academia.sh/tr/kurslar/dayaniklilik-kaliplari'
language: tr
updated: '2026-08-17T04:43:07+00:00'
license: 'CC BY-SA 4.0'
lessons: 20
outcomes:
    - 'Arıza kiplerini önceden belirleyip yalıtım kalıpları uygular'
    - 'Devralma ve kurtarma hedeflerini sayısal olarak tanımlar'
    - 'Dağıtık iş akışlarında telafi mekanizmaları kurar'
---

# Dayanıklılık ve Güvenilirlik

Parçaların çalıştığı varsayımının kaldırılması: kısmi arıza, yavaşlama ve ağ bölünmesinin arıza kipi olarak adlandırılması, devre kesici, bölme kalıbı, yeniden deneme, zaman aşımı bütçesi, geri basınç, kısıtlama ve zarif bozulma ile arızanın yayılmasının kesilmesi, devralma ile kurtarma hedeflerinin kesinti bütçesine bağlanması ve dağıtık iş akışlarında etkisizlik, telafi edici işlem ile aşamalı geçiş düzenlerinin kurulması; her kalıbın arızasız gündeki bedeli ve arızalı gündeki kazancı ayrı ayrı sayılır.

## Arıza Yalıtımı

Bir bileşenin arızasının sistemin tamamına yayılmasını kesen kalıplar: kısmi arıza, yavaşlama ve ağ bölünmesinin ayrı arıza kipleri olarak tanınması, bozuk bağımlılığın devre kesiciyle devreden çıkarılması, kaynak havuzlarının bölmelerle ayrıştırılması, yeniden denemenin fırtınaya dönüşme riski, zaman aşımı süresinin zincir boyunca bütçelenmesi, aşırı yükün kaynağa geri bildirilmesi, denetimli hizmet reddi ve çekirdek işlevin korunarak bozulma.

### Arıza Kipleri

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/ariza-kipleri

Parçaların çalıştığı varsayımının kaldırılması: kısmi arıza, yavaşlama, bayat içerik ve ağ bölünmesinin ayrı arıza kipleri olarak adlandırılması, kipin çağıran gözünden imzasıyla ayırt edilmesi, iki kipin aynı imzayı verdiği yerin gösterilmesi ve aynı bileşenin durmasıyla yavaşlamasının bulaşma kapsamı cinsinden karşılaştırılması.

Dört kurs boyunca sistem bir kez bile bozulmadı. İstek uçtan girdi, önbellekten geçti, dengelendi,
bir servise düştü, bir depoya vardı ve döndü; her hesap parçaların **çalıştığını** varsaydı. Bu
varsayım kaldırıldığında ilk soru "ne yapmalı" değildir, "ne oldu"dur. Bir bağımlılık cevap
vermediğinde çağıranın elinde yalnız kendi gözlemi vardır ve aynı gözlemin arkasında çok farklı
bozulmalar durabilir; doğru tepki hangisinin olduğuna bağlıdır.

Bu ders bir kalıp kurmaz; kursun ilk kalıbı sonraki derstedir. Kurduğu şey bir **sözlüktür**:
bozulma biçimleri adlandırılır, çağıranın gözünden nasıl göründükleri ölçülür ve her birinin
sistemin kaçına bulaştığı sayılır.

#### Sözlük: Beş Bozulma Biçimi

**Arıza kipi**, bir bileşenin bozulma biçimidir: ne yaptığı değil, **nasıl** yanlış yaptığı. Sistemin
kendi yapısından beş senaryo çıkar ve her biri bir kipin örneğidir.

- **Durma.** Bir parça düğümü düşüyor; çağrı anında hata dönüyor.
- **Yavaşlama.** Taşıyıcı bildirim ucu yavaşlıyor; yanıt geliyor ama çağıranın bekleyebileceğinden
  uzun sürede.
- **Kısmi arıza.** Sekiz parçanın biri düşüyor; çağrıların bir bölümü hata alıyor, kalanı yanıt.
- **Bayat içerik.** İzdüşümü besleyen kütük tüketicisi geri kalıyor; yanıt hızlı ve biçimi doğru,
  içeriği eski.
- **Ağ bölünmesi.** İki bölge arasındaki bağ kopuyor; iki yan da ayakta, birbirini göremiyor.

Ağ bölünmesi burada yalnız bir arıza kipi olarak tanınır; bölünme altında tutarlılık ile hizmet
erişilebilirliği arasında verilecek karar Sistem Tasarımına Giriş kursunda kuruldu. **Ağ bölünmesi**
ile İlişkisel Veritabanı Yönetimi kursunun **bölümleme**si ve Veri Katmanı Ölçekleme kursunun
**parçalama**sı ayrı kavramlardır: ilk ikisi veriyi bölme kararıdır, buradaki bölünme istenmeden
olan bir kopmadır.

Beşine bir altıncı eklenir ve sözlüğün sınırını gösterir: **gün sonu ücretlendirme işi yarıda
kalıyor.** Hiçbir çağrı hata vermez, hiçbiri yavaşlamaz; aşağıdaki ölçüm bu kipi **hiç göremez**.
Bir kipi görebilmek için ona bakan bir gözlem gerekir.

#### Çağıranın Gördüğü İmza

Aşağıdaki koşum bir **modeldir**. Tur soyut bir adımdır; gerçek ağ, küme ya da kapsayıcı kurulmaz,
bağımlılığın davranışı parametredir ve rastgelelik kendi yazılmış, tohumlanmış bir üreteçten gelir.
Varsayımlar bu kursun kendi varsayımlarıdır, K01'in tablosuna eklenmez.

**AY1 — tur–saniye çevrimi: 1 tur = 10 ms.** Gerekçe: Uygulama Katmanı ve Servis Etkileşimi kursu
bir adım çağrısının olağan süresini 8 ms saymıştı; iki turluk çağrı 20 ms eder.

**AY2 — bileşen başına 32 eşzamanlı yuva, zaman aşımı 20 tur.** Gerekçe: 20 tur AY1 ile tam 200
ms'dir, yani K01'in okuma eşiğinin kendisi; 32 yuva arızasız günde 0,78 tepe doluluk verir.
Duyarlılıkları ikinci koşumda basılır.

**AY4 — arızasız günde çağrıların 0,025'i zaman aşımına uğrar.** Gerekçe: kısa gecikmeler arıza
olmadan da olur. Duyarlılığı aşağıda 0,050 ile verilir.

```js
// kipler/gorunum.mjs — alti ariza kipinin CAGIRAN gozunden imzasi. MODELDIR: tur soyut bir adim,
// bagimliligin davranisi parametre, rastgelelik tohumlu bir uretecten.
const N = 400, OLAGAN = 2, ZT = 20;   // cagri sayisi; olagan cagri 2 tur; AY2: zaman asimi 20 tur
const PARCA = 8, DUSEN = 1;           // kismi ariza: sekiz parcanin biri dustu (M19/K04)
const SEYREK = 0.025;                 // AY4: arizasiz gunde cagrilarin 1/40'i zaman asimina ugrar
let s = 20260730 % 2147483647;
const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
const YANIT = { sinif: "yanit", tur: OLAGAN, taze: true };
const HATA = { sinif: "hata", tur: 1, taze: null };
const ASIM = { sinif: "zamanAsimi", tur: ZT, taze: null };

function cagri(kip) {                 // tek cagrinin sonucu: sinif, tutulan tur, icerik tazeligi
  if (kip === "durma") return HATA;
  if (kip === "yavaslama" || kip === "bolunme") return ASIM;
  if (kip === "bayat") return { ...YANIT, taze: false };
  if (kip === "kismi") return rast() < DUSEN / PARCA ? HATA : YANIT;
  return rast() < SEYREK ? ASIM : YANIT;
}

function imza(kip) {                  // N cagrinin imza vektoru
  const c = Array.from({ length: N }, () => cagri(kip));
  const y = c.filter((x) => x.sinif === "yanit");
  const oran = (t) => c.filter((x) => x.sinif === t).length / N;
  return { yanit: y.length / N, hata: oran("hata"), asim: oran("zamanAsimi"),
    yuvaTur: c.reduce((t, x) => t + x.tur, 0) / N,
    taze: y.length === 0 ? null : y.filter((x) => x.taze).length / y.length };
}

const KIP = ["saglikli", "durma", "yavaslama", "kismi", "bayat", "bolunme"];
const b = (x) => (x === null ? "-" : x.toFixed(3));
const imzalar = Object.fromEntries(KIP.map((k) => [k, imza(k)]));

console.log(`model: kip basina ${N} cagri, olagan cagri ${OLAGAN} tur, zaman asimi ${ZT} tur, tohum 20260730`);
console.log(`\n${"kip".padEnd(11)}${"yanit".padStart(7)}${"hata".padStart(7)}${"zaman asimi".padStart(13)}` +
  `${"yuva-tur/cagri".padStart(16)}${"taze icerik".padStart(13)}`);
for (const k of KIP) {
  const i = imzalar[k];
  console.log(`${k.padEnd(11)}${b(i.yanit).padStart(7)}${b(i.hata).padStart(7)}${b(i.asim).padStart(13)}` +
    `${i.yuvaTur.toFixed(2).padStart(16)}${b(i.taze).padStart(13)}`);
}

const esit = (a, c, alan) => alan.every((k) => Math.abs((a[k] ?? -1) - (c[k] ?? -1)) < 0.02);
console.log("\nsinif oranlariyla ayrilamayan kip ciftleri:");
for (let i = 0; i < KIP.length; i += 1)
  for (let j = i + 1; j < KIP.length; j += 1)
    if (esit(imzalar[KIP[i]], imzalar[KIP[j]], ["yanit", "hata", "asim"]))
      console.log(`  ${KIP[i]} = ${KIP[j]} -> icerik denetimi ` +
        `${esit(imzalar[KIP[i]], imzalar[KIP[j]], ["taze"]) ? "de ayirmiyor" : "ayiriyor"}`);

const PENCERE = 20, DAMGA = 8, OLAY = 97.22, UCTA = 513.89, CEVRIM = 100;  // K01 hizlari; AY1
console.log(`\narizasiz gunun bedeli: yanit basina ${DAMGA} baytlik tazelik damgasi = ` +
  `${(DAMGA * UCTA).toFixed(2)} bayt/s (K01 uctaki ${UCTA} istek/s); adlandirma ${PENCERE} cagri = ` +
  `${(PENCERE / (OLAY / CEVRIM)).toFixed(1)} tur (${OLAY} olay/s) = ` +
  `${((PENCERE / (OLAY / CEVRIM) * 1000) / CEVRIM).toFixed(0)} ms`);
console.log(`duyarlilik: AY4 0,050 olsaydi yuva-tur/cagri ${imzalar.saglikli.yuvaTur.toFixed(2)} yerine ` +
  `${(OLAGAN + 0.05 * (ZT - OLAGAN)).toFixed(2)} olurdu`);
```

```
model: kip basina 400 cagri, olagan cagri 2 tur, zaman asimi 20 tur, tohum 20260730

kip          yanit   hata  zaman asimi  yuva-tur/cagri  taze icerik
saglikli     0.988  0.000        0.013            2.23        1.000
durma        0.000  1.000        0.000            1.00            -
yavaslama    0.000  0.000        1.000           20.00            -
kismi        0.880  0.120        0.000            1.88        1.000
bayat        1.000  0.000        0.000            2.00        0.000
bolunme      0.000  0.000        1.000           20.00            -

sinif oranlariyla ayrilamayan kip ciftleri:
  saglikli = bayat -> icerik denetimi ayiriyor
  yavaslama = bolunme -> icerik denetimi de ayirmiyor

arizasiz gunun bedeli: yanit basina 8 baytlik tazelik damgasi = 4111.12 bayt/s (K01 uctaki 513.89 istek/s); adlandirma 20 cagri = 20.6 tur (97.22 olay/s) = 206 ms
duyarlilik: AY4 0,050 olsaydi yuva-tur/cagri 2.23 yerine 2.90 olurdu
```

Bu sayılar **ölçüm** sınıfındadır: bu makinede koşan bir modelden çıkarlar, belirlenimlidirler.

Tablonun en önemli sütunu **yuva-tur/çağrı**dır: çağıranın o çağrı için eşzamanlılık yuvasını kaç
tur tuttuğu. Durma 1,00, yavaşlama 20,00. **Duran bir bağımlılık çağıranın kaynağını boşaltır,
yavaşlayan bir bağımlılık onu tutar** — aynı çağrı için yirmi kat fark. Kısmi arıza ikisinin
arasındadır: hata oranı 0,120, yani sekizde bir; çağıran yeniden denerse sağlam bir parçaya düşme
olasılığı vardır, durmada böyle bir umut yoktur. Bayat içerik ise sınıf oranlarında **sağlıklıdan
ayırt edilemez** — onu ayıran tek şey yanıtın taşıdığı tazelik damgasıdır.

Son satır dersin ayırt etme sınırıdır. **Yavaşlama ile ağ bölünmesi çağıran gözünden aynı şeydir**
ve içerik denetimi de onları ayırmaz: ikisinde de yanıt yoktur, ikisinde de yuva zaman aşımına kadar
tutulur. Fark çağrının kendisinde değildir — bölünmede öteki yan **ayaktadır ve isteği işlemiş
olabilir.** Yavaşlamada yeniden denenen bir yazma gecikir, bölünmede iki kez uygulanabilir.

Sözlüğün arızasız gündeki bedeli son iki satırdadır: bayat içeriği görebilmek için her yanıta 8
baytlık bir tazelik damgası eklenir (K01'in uçtaki 513,89 istek/s'sinde 4111,12 bayt/s) ve
adlandırma yirmi çağrılık bir pencere ister — taşıyıcı olay hızında 20,6 tur, yani 206 ms.

#### Bulaşma Kapsamı

Bir arızanın bedeli bozulan bileşende değil, **bulaştığı yerdedir**. **Bulaşma kapsamı** (blast
radius), arıza sırasında hizmet veremeyen bileşenlerin ve etkilenen istek hızının ölçüsüdür. İkinci
koşum sistemi bir çağrı ağacı olarak modeller: bir akışın bir bileşende tuttuğu yuva sayısı **akış
hızı çarpı tutuş süresidir**; toplam tutuş havuzu aşarsa bileşen **doygun** olur ve kendi çağıranına
yavaş görünür.

```js
// kipler/bulasma.mjs — ariza kipinin bulasma kapsami. MODELDIR: yayilma yuva dolulugundan cikar.
// Hizlar K01'in tepe hesabindan, yapi K02-K04'ten gelir.
const CEVRIM = 100, YUVA = 32, ZT = 20, OLAGAN = 2;   // AY1: 1 tur = 10 ms; AY2: yuva ve zaman asimi
const d = (ad, ...alt) => ({ ad, alt });
const AKIS = [                                        // K01 tepe: 416,67 + 97,22 = 513,89 istek/s
  { ad: "takip sorgusu", hiz: 416.67, kok: d("ag-gecidi", d("takip-servisi", d("izdusum-deposu"))) },
  { ad: "durum olayi", hiz: 97.22,
    kok: d("ag-gecidi", d("olay-ucu", d("tasiyici-dogrulama"), d("durum-deposu"))) },
  { ad: "gun sonu isi", hiz: 833.33, kok: d("gun-sonu-isi", d("durum-deposu")) },
  { ad: "kutuk tuketimi", hiz: 97.22, kok: d("kutuk-tuketicisi", d("durum-deposu"), d("izdusum-deposu")) },
];

function tut(n, ariza, kip) {           // tutulan tur; ilk basarisizlikta kalan cagri yapilmaz
  if (n.ad === ariza) return kip === "durma" ? { tur: 1, ok: false } : { tur: ZT, ok: false };
  if (n.alt.length === 0) return { tur: OLAGAN, ok: true };
  let tur = 1, ok = true;
  for (const c of n.alt) { const r = tut(c, ariza, kip); tur += r.tur; if (!r.ok) { ok = false; break; } }
  return { tur, ok };
}

function kosum(ariza, kip) {            // bilesen basina doluluk = akis hizi x tutus suresi
  const dolu = {}, gecen = {};
  const gez = (n, a) => {
    dolu[n.ad] = (dolu[n.ad] ?? 0) + (a.hiz / CEVRIM) * tut(n, ariza, kip).tur;
    (gecen[n.ad] ??= new Set()).add(a.ad);
    n.alt.forEach((c) => gez(c, a));
  };
  AKIS.forEach((a) => gez(a.kok, a));
  const doygun = Object.keys(dolu).filter((k) => dolu[k] >= YUVA);
  const vurulan = new Set(ariza ? [...doygun, ariza] : doygun);
  const akis = new Set([...vurulan].flatMap((v) => [...gecen[v]]));
  const hiz = [...akis].reduce((t, a) => t + AKIS.find((x) => x.ad === a).hiz, 0);
  return { dolu, doygun, bulasan: vurulan.size, akis: akis.size, hiz };
}

const t = kosum(null, null);
console.log(`model: ${Object.keys(t.dolu).length} bilesen, ${AKIS.length} akis, bilesen basina ${YUVA} ` +
  `yuva, zaman asimi ${ZT} tur, 1 tur = ${1000 / CEVRIM} ms\n`);
console.log(`arizasiz gun: ` + Object.entries(t.dolu)
  .map(([k, v]) => `${k} ${(v / YUVA).toFixed(3)}`).join(", "));

console.log(`\n${"arizali bilesen".padEnd(20)}${"kip".padEnd(11)}${"bulasan".padStart(8)}` +
  `${"doygun olan".padStart(42)}${"akis".padStart(6)}${"etkilenen istek/s".padStart(19)}`);
for (const bil of ["tasiyici-dogrulama", "izdusum-deposu", "durum-deposu"])
  for (const kip of ["durma", "yavaslama"]) {
    const r = kosum(bil, kip);
    console.log(`${bil.padEnd(20)}${kip.padEnd(11)}${String(r.bulasan).padStart(8)}` +
      `${(r.doygun.join(",") || "-").padStart(42)}${`${r.akis}/${AKIS.length}`.padStart(6)}` +
      `${r.hiz.toFixed(2).padStart(19)}`);
  }

const dur = kosum("tasiyici-dogrulama", "durma"), yav = kosum("tasiyici-dogrulama", "yavaslama");
const g = (r) => (r.dolu["ag-gecidi"] / YUVA).toFixed(3);
console.log(`\ntasiyici dogrulamasi: durma ${dur.hiz.toFixed(2)} istek/s ve ${dur.bulasan} bilesen, ` +
  `yavaslama ${yav.hiz.toFixed(2)} ve ${yav.bulasan} -> x${(yav.hiz / dur.hiz).toFixed(2)} istek`);
console.log(`ag gecidi dolulugu: arizasiz ${g(t)} -> durmada ${g(dur)} -> yavaslamada ${g(yav)}`);
console.log(`duyarlilik: yuva 48 olsaydi yavaslamada doluluk ${(yav.dolu["ag-gecidi"] / 48).toFixed(3)} ` +
  `(tasmaz), 1 tur 20 ms olsaydi ${(2 * yav.dolu["ag-gecidi"] / YUVA).toFixed(3)}`);

const SAYI = 3, SURE = 10, PAY = 28.2;  // AY3; K01 temel-nitelikler/04: aylik ariza payi (dakika)
console.log(`\nAY3: ayda ${SAYI} x ${SURE} dk = ${SAYI * SURE} dk, K01'in ${PAY} dk'lik ariza payinin ` +
  `%${((100 * SAYI * SURE) / PAY).toFixed(1)}'i (sure 5 dk olsaydi %${((100 * SAYI * 5) / PAY).toFixed(1)})`);
console.log(`ayni ${SAYI * SURE} dakika: durma ${(SAYI * SURE * 60 * dur.hiz).toFixed(0)} istek, ` +
  `yavaslama ${(SAYI * SURE * 60 * yav.hiz).toFixed(0)} istek, fark ${(SAYI * SURE * 60 * (yav.hiz - dur.hiz)).toFixed(0)}`);
```

```
model: 8 bilesen, 4 akis, bilesen basina 32 yuva, zaman asimi 20 tur, 1 tur = 10 ms

arizasiz gun: ag-gecidi 0.703, takip-servisi 0.391, izdusum-deposu 0.321, olay-ucu 0.152, tasiyici-dogrulama 0.061, durum-deposu 0.642, gun-sonu-isi 0.781, kutuk-tuketicisi 0.152

arizali bilesen     kip         bulasan                               doygun olan  akis  etkilenen istek/s
tasiyici-dogrulama  durma             1                                         -   1/4              97.22
tasiyici-dogrulama  yavaslama         2                                 ag-gecidi   2/4             513.89
izdusum-deposu      durma             1                                         -   2/4             513.89
izdusum-deposu      yavaslama         3    ag-gecidi,takip-servisi,izdusum-deposu   3/4             611.11
durum-deposu        durma             1                                         -   3/4            1027.77
durum-deposu        yavaslama         3       ag-gecidi,durum-deposu,gun-sonu-isi   4/4            1444.44

tasiyici dogrulamasi: durma 97.22 istek/s ve 1 bilesen, yavaslama 513.89 ve 2 -> x5.29 istek
ag gecidi dolulugu: arizasiz 0.703 -> durmada 0.612 -> yavaslamada 1.189
duyarlilik: yuva 48 olsaydi yavaslamada doluluk 0.793 (tasmaz), 1 tur 20 ms olsaydi 2.378

AY3: ayda 3 x 10 dk = 30 dk, K01'in 28.2 dk'lik ariza payinin %106.4'i (sure 5 dk olsaydi %53.2)
ayni 30 dakika: durma 174996 istek, yavaslama 925002 istek, fark 750006
```

Gün sonu işi kendi penceresinde koşar; çevrimiçi akışlarla birlikte gösterilmesi en kötü durumu
verir.

#### Aynı Bileşen, İki Kip, Beş Kat Fark

Okuma tek bir satır çiftinden başlar. Taşıyıcı doğrulaması **durduğunda** olay ucu bir turda hata
alır, yuvasını bırakır, isteği reddeder. Etkilenen tek akış durum olayıdır: 97,22 istek/s ve bir
bileşen. Takip sorgusu hiç etkilenmez.

Aynı bağımlılık **yavaşladığında** olay ucu her çağrıda yuvasını yirmi tur tutar ve bu tutuş yukarı
taşınır: ağ geçidinin olay ucunu çağıran bacağı 6 turdan 22 tura çıkar, doluluk 0,703'ten 1,189'a
gider ve geçit **doygun** olur. O anda takip sorgusu da yanıtlanamaz — oysa bozuk bağımlılığa hiç
dokunmaz. Etkilenen hız 513,89 istek/s, bulaşan bileşen 2: **5,29 kat istek.**

Bu, kursun ilk yasasıdır ve sonraki üç dersin gerekçesidir: **yavaşlama durmadan pahalıdır.** Duran
bir bağımlılık kendi akışını öldürür ve orada durur; yavaşlayan bir bağımlılık paylaşılan kaynağı
tüketerek ilgisiz akışları da düşürür. Durma kipinde geçidin doluluğu 0,703'ten **0,612'ye iner** —
arıza geçidi rahatlatır, çünkü reddedilen istekler kaynak tutmaz.

Kalan satırlar aynı örüntüyü doğruluyor. İzdüşüm deposu durduğunda 513,89 istek/s etkilenir;
yavaşladığında zincirin tamamı doyar ve hız 611,11 olur. Durum deposu durduğunda 1027,77 istek/s
etkilenir ama hiçbir bileşen doymaz; yavaşladığında dört akış birden vurulur, 1444,44 istek/s.

Duyarlılık satırı doygunluğun neye bağlı olduğunu söylüyor. Havuz 48 yuva olsaydı yavaşlamada
doluluk 0,793'te kalır, geçit taşmaz ve bulaşma iki bileşenden bire inerdi; tur 20 ms olsaydı
doluluk 2,378 olurdu. **Bulaşma kapsamı arızanın kendisinden değil, havuz boyutu ile zaman aşımının
çarpımından çıkar.**

Son iki satır iki günü kesinti bütçesine bağlıyor. AY3 — **yavaşlama ayda 3 kez oluyor ve her biri
10 dakika sürüyor.** Gerekçe: K01 kurtarma süresini 10 dakika varsaymış ve aylık 28,2 dakikalık
arıza payına 2,82 arıza sığdırmıştı; üç arıza o payın yüzde 106,4'ünü yer. Duyarlılık: süre 5
dakika olsaydı pay yüzde 53,2'ye inerdi. Aynı 30 dakika durma kipinde 174.996, yavaşlama kipinde
925.002 isteği vurur — **750.006 istek fark.** Sözlüğün arızalı gündeki kazancı budur: hiçbir
arızayı kesmez, ama iki kipi karıştırmanın kaç istek ettiğini sayılabilir kılar.

#### Özet

- Arıza kipi bir bileşenin bozulma biçimidir; senaryolar beş kipe karşılık gelir — durma, yavaşlama,
  kısmi arıza, bayat içerik, ağ bölünmesi. Yarıda kalan toplu iş çağrı gözlemiyle görülemez.
- İmza kipleri kısmen ayırır: durma 1,00 yuva-tur ve 1,000 hata; yavaşlama 20,00 yuva-tur ve 1,000
  zaman aşımı; kısmi arıza 0,120 hata; bayat içerik sağlıklıdan yalnız tazelik damgasıyla ayrılır.
- Yavaşlama ile ağ bölünmesi çağıran gözünden aynıdır ve içerik denetimi de onları ayırmaz; fark
  bölünmede öteki yanın ayakta olması ve isteği işlemiş olabilmesidir.
- Arızasız günün bedeli her yanıta eklenen 8 baytlık damga (4111,12 bayt/s) ve adlandırma için
  gereken 20 çağrılık penceredir (97,22 olay/s'de 20,6 tur, 206 ms).
- Bulaşma kapsamı kipe bağlıdır: taşıyıcı doğrulaması durduğunda 97,22 istek/s ve 1 bileşen,
  yavaşladığında 513,89 istek/s ve 2 bileşen — 5,29 kat. Ağ geçidi doluluğu 0,703'ten durmada
  0,612'ye iner, yavaşlamada 1,189'a çıkar.
- AY3'ün 30 dakikasında iki kip arasındaki fark 750.006 istektir ve o 30 dakika K01'in aylık arıza
  payının yüzde 106,4'üdür.

#### Sonraki Adım

Ölçüm bir yön gösteriyor. Yavaşlamanın pahalı olmasının nedeni bağımlılığın bozuk olması değil,
çağıranın **bozuk bağımlılığı çağırmayı sürdürmesidir**: her çağrı bir yuvayı yirmi tur tutar ve o
yuvalar hiçbir işe yaramaz. Aynı tablo çareyi de gösteriyor — durma kipinde doluluk 0,612'ye
**iniyor**, çünkü hızlı hata kaynak tutmaz. Yavaşlayan bir bağımlılığı çağırmayı bırakmak,
yavaşlamayı durmaya çevirir ve bulaşmayı 513,89'dan 97,22 istek/s'ye indirir. Sonraki ders bu kararı
veren bileşeni tasarlar: kesmeye hangi eşikte karar verildiği, kesikken kaç çağrının hiç yapılmadığı
ve sağlıklı bir bağımlılığın yanlışlıkla kesilmesinin kaça mal olduğu orada sayılır.

### Devre Kesici

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/devre-kesici

Bozuk bağımlılığın devreden çıkarılması: kesicinin servisler arasında paylaşılan yuva havuzunu koruması, eşiğin arıza kipine göre seçilmesi, ardışık sayı ile pencere oranı kurallarının dört kipte karşılaştırılması, açık durumda tasarruf edilen çağrı ile kurtarılan komşu isteğin sayılması ve sağlıklı bir bağımlılığı kesen yanlış açılmanın reddedilen geçerli istek cinsinden bedeli.

Önceki ders bir yön bıraktı: yavaşlayan bir bağımlılığı çağırmayı bırakmak yavaşlamayı durmaya
çevirir ve bulaşmayı 513,89 istek/s'den 97,22 istek/s'ye indirir. Bu dersin işi o cümleyi bir
bileşene dönüştürmek ve gerçekten öyle olup olmadığını aynı arıza senaryosunda ölçmektir.

**Devre kesici**, bir bağımlılığın son çağrılarının sonucuna bakarak o bağımlılığa yapılan çağrıyı
bir süre için hiç yapmayan bileşendir. Üç durumu vardır ve bu durumlar Uygulama Mimarisi kursunda
kuruldu: **kapalı** durumda çağrı geçer, **açık** durumda çağrı hiç yapılmaz ve çağıran anında
başarısızlık alır, **yarı açık** durumda tek bir yoklama çağrısı geçirilir ve sonucuna göre ya
kapalıya dönülür ya yeniden açılır. Geçiş mekaniği burada yeniden anlatılmaz.

Servisler arasında değişen üç şey vardır. Birincisi, kesicinin koruduğu kaynak çağıranın **yuva
havuzudur** ve o havuz başka akışlarla paylaşılır — kesici bozuk bağımlılığı değil, onunla aynı
havuzu kullanan akışları korur. İkincisi, eşik bir tercih değil **arıza kipine bağlı bir seçimdir**;
aynı eşik durmada ucuz, yavaşlamada pahalı, kısmi arızada yanlıştır. Üçüncüsü, açık durumda
reddedilen istekler gerçek isteklerdir ve bir yere gitmek zorundadır.

#### Kesicisiz ve Kesicili Aynı Senaryo

Aşağıdaki koşum 01. dersin modelini turlara açar. Yuva havuzu ağ geçidindedir ve takip sorgusuyla
durum olayı arasında paylaşılır; bağımlılığın kipi parametredir. Yine bir **modeldir** — gerçek
küme, kapsayıcı ya da kaos aracı kurulmaz, rastgelelik tohumlu bir üreteçtendir.

**AY5 — kesicinin kuralı: son 20 çağrının 0,50'si başarısızsa aç, 100 tur (1 saniye) kesik kal.**
Gerekçe: 20 çağrı, taşıyıcı olay hızında yaklaşık 20 turluk bir penceredir, yani K01'in okuma eşiği
kadar; 0,50 eşiği kısmi arızanın 0,125'lik başarısızlık oranı ile durma ve yavaşlamanın 1,000'i
arasında durur. Duyarlılığı kesik süresi 200 tur ile aşağıda basılır.

```js
// kesici/kosum.mjs — ayni ariza senaryosunun kesicisiz ve kesicili kosumu. MODELDIR: tur soyut bir
// adim, ag gecidinin yuva havuzu iki akis arasinda paylasilir, bagimliligin kipi parametredir.
const YUVA = 32, CEVRIM = 100, T = 1200, BAS = 200;   // AY2, AY1; 12 s kosum, ariza 2. saniyede
const TAKIP = 416.67, OLAY = 97.22, TAKIP_TUTUS = 4;  // K01 tepe hizlari; 01. ders: takip bacagi 4 tur
const KIP = {                                         // p: cagrinin basarisizlik olasiligi
  saglikli: { p: 0.025, ok: 6, hata: 22 },            // AY4: seyrek zaman asimi, yuvayi 22 tur tutar
  kismi: { p: 0.125, ok: 6, hata: 3 },                // sekiz parcanin biri: hizli hata
  durma: { p: 1, ok: 6, hata: 3 },
  yavaslama: { p: 1, ok: 6, hata: 22 },
};

function kosum({ kip, kural }) {
  let s = 20260731 % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const serbest = new Array(YUVA).fill(0);
  const c = { takipYanit: 0, takipYuvasiz: 0, olayYanit: 0, olayRed: 0, olayHata: 0, olayYuvasiz: 0,
    cagri: 0, olayYuvaTur: 0, acilma: 0, algilamaTur: null, algilamaYuvaTur: null };
  let birikT = 0, birikO = 0, durum = "kapali", ardisik = 0, acikBitis = 0, pencere = [], basY = 0;

  const yuvaAl = (t, sure) => {
    const i = serbest.findIndex((x) => x <= t);
    if (i < 0) return false;
    serbest[i] = t + sure; return true;
  };
  const acildi = (t) => {                     // kesici kapalidan acige gectiginde
    c.acilma += 1; durum = "acik"; acikBitis = t + kural.kesik; ardisik = 0; pencere = [];
    if (c.algilamaTur === null && t >= BAS && kip !== "saglikli") { c.algilamaTur = t - BAS; c.algilamaYuvaTur = c.olayYuvaTur - basY; }
  };

  for (let t = 0; t < T; t += 1) {
    if (t === BAS) basY = c.olayYuvaTur;
    if (durum === "acik" && t >= acikBitis) durum = "yariAcik";
    birikT += TAKIP / CEVRIM; birikO += OLAY / CEVRIM;
    const gelen = [];                          // turun icindeki varislar karistirilir (tohumlu)
    for (let n = Math.floor(birikT); n > 0; n -= 1, birikT -= 1) gelen.push("takip");
    for (let n = Math.floor(birikO); n > 0; n -= 1, birikO -= 1) gelen.push("olay");
    for (let i = gelen.length - 1; i > 0; i -= 1) {
      const j = Math.floor(rast() * (i + 1));
      [gelen[i], gelen[j]] = [gelen[j], gelen[i]];
    }

    for (const akis of gelen) {
      if (akis === "takip") { if (yuvaAl(t, TAKIP_TUTUS)) c.takipYanit += 1; else c.takipYuvasiz += 1; continue; }
      if (durum === "acik") { c.olayRed += 1; yuvaAl(t, 1); continue; }   // kesik: cagri hic yapilmaz
      const k = KIP[kip === "saglikli" || t < BAS ? "saglikli" : kip];
      const basarisiz = rast() < k.p;
      const sure = basarisiz ? k.hata : k.ok;
      if (yuvaAl(t, sure) === false) { c.olayYuvasiz += 1; continue; }
      c.cagri += 1; c.olayYuvaTur += sure;
      if (basarisiz) c.olayHata += 1; else c.olayYanit += 1;
      if (kural === null) continue;                    // kalipsiz kosum: durum tutulmaz
      if (durum === "yariAcik") { if (basarisiz) acildi(t); else { durum = "kapali"; ardisik = 0; pencere = []; } continue; }
      if (kural.tur === "ardisik") {
        ardisik = basarisiz ? ardisik + 1 : 0;
        if (ardisik >= kural.esik) acildi(t);
      } else {
        pencere.push(basarisiz ? 1 : 0);
        if (pencere.length > kural.pencere) pencere.shift();
        if (pencere.length === kural.pencere &&
          pencere.reduce((a, x) => a + x, 0) / kural.pencere >= kural.esik) acildi(t);
      }
    }
  }
  return c;
}

const ORAN = { tur: "oran", pencere: 20, esik: 0.5, kesik: 100 };   // AY5
const b = (x) => x.toFixed(2);
const OLCUT = ["takipYanit", "takipYuvasiz", "olayYanit", "olayRed", "olayHata", "cagri", "olayYuvaTur"];
const BASLIK = ["takip yanit", "takip yuvasiz", "olay yanit", "olay red", "olay hata", "yapilan cagri", "olay yuva-tur"];

console.log(`model: ${T} tur (${T / CEVRIM} s), ariza ${BAS}. turda, ${YUVA} yuva; secilen kural: son ` +
  `${ORAN.pencere} cagrinin ${ORAN.esik}'si basarisizsa ac, ${ORAN.kesik} tur kesik kal`);
console.log(`\n${"kosum".padEnd(24)}` + BASLIK.map((x) => x.padStart(15)).join(""));
const r = {};
for (const kip of ["saglikli", "kismi", "yavaslama", "durma"])
  for (const [ek, kural] of [["kesicisiz", null], ["kesicili", ORAN]]) {
    const ad = `${kip}, ${ek}`;
    r[ad] = kosum({ kip, kural });
    console.log(`${ad.padEnd(24)}` + OLCUT.map((k) => String(r[ad][k]).padStart(15)).join(""));
  }

const s1 = r["saglikli, kesicili"];
const [k0, k1] = [r["kismi, kesicisiz"], r["kismi, kesicili"]];
const [y0, y1] = [r["yavaslama, kesicisiz"], r["yavaslama, kesicili"]];
const [d0, d1] = [r["durma, kesicisiz"], r["durma, kesicili"]];
const olcek = (600 * CEVRIM) / (T - BAS);          // AY3: 10 dakikalik arizaya olcekleme
console.log(`\narizasiz gunun bedeli: ${s1.cagri} cagrinin hepsinde kesici sorgulanir ve ` +
  `${ORAN.pencere} kayitlik pencere tutulur; ${s1.acilma} yanlis acilma, ${s1.olayRed} reddedilen gecerli olay; ` +
  `kismi arizada ${k1.acilma} acilma ve olay yanit ${k0.olayYanit} -> ${k1.olayYanit} ` +
  `(${k0.olayYanit - k1.olayYanit} basarili olabilecek olay reddedildi)`);
console.log(`arizali gunun kazanci (yavaslama): takip yuvasiz ${y0.takipYuvasiz} -> ${y1.takipYuvasiz}, ` +
  `olay yuva-tur ${y0.olayYuvaTur} -> ${y1.olayYuvaTur} (%${b((100 * (y0.olayYuvaTur - y1.olayYuvaTur)) / y0.olayYuvaTur)} az), ` +
  `bozuk bagimliliga cagri ${y0.cagri} -> ${y1.cagri}`);
console.log(`ayni kazanc durmada: takip yuvasiz ${d0.takipYuvasiz} -> ${d1.takipYuvasiz}, ` +
  `olay yuva-tur ${d0.olayYuvaTur} -> ${d1.olayYuvaTur}, cagri ${d0.cagri} -> ${d1.cagri}`);
console.log(`AY3'un 10 dakikasina olcek: yavaslamada tasarruf edilen cagri ` +
  `${((y0.cagri - y1.cagri) * olcek).toFixed(0)}, kurtarilan takip istegi ` +
  `${((y0.takipYuvasiz - y1.takipYuvasiz) * olcek).toFixed(0)}`);

console.log(`\n${"kural".padEnd(18)}${"kip".padEnd(11)}${"algilama turu".padStart(14)}` +
  `${"algilamaya kadar yuva-tur".padStart(26)}${"acilma".padStart(8)}${"reddedilen gecerli olay".padStart(25)}`);
const KURAL = [
  ["ardisik 5", { tur: "ardisik", esik: 5, kesik: 100 }],
  ["oran 0,50 / 20", { tur: "oran", pencere: 20, esik: 0.5, kesik: 100 }],
  ["oran 0,10 / 20", { tur: "oran", pencere: 20, esik: 0.1, kesik: 100 }],
];
for (const [ad, kural] of KURAL)
  for (const kip of ["saglikli", "kismi", "yavaslama", "durma"]) {
    const k = kosum({ kip, kural });
    const kayip = kip === "kismi" ? k0.olayYanit - k.olayYanit : k.olayRed;
    console.log(`${ad.padEnd(18)}${kip.padEnd(11)}${String(k.algilamaTur ?? "-").padStart(14)}` +
      `${String(k.algilamaYuvaTur ?? "-").padStart(26)}${String(k.acilma).padStart(8)}` +
      `${String(kip === "saglikli" || kip === "kismi" ? kayip : "-").padStart(25)}`);
  }
const uzun = { ...ORAN, kesik: 200 }, dar = { tur: "oran", pencere: 20, esik: 0.1, kesik: 200 };
console.log(`duyarlilik: kesik suresi ${ORAN.kesik} yerine ${uzun.kesik} tur olsaydi yavaslamada yapilan ` +
  `cagri ${y1.cagri} -> ${kosum({ kip: "yavaslama", kural: uzun }).cagri}; oran 0,10 kuralinda arizasiz ` +
  `gunde reddedilen gecerli olay ${kosum({ kip: "saglikli", kural: KURAL[2][1] }).olayRed} -> ` +
  `${kosum({ kip: "saglikli", kural: dar }).olayRed}`);
```

```
model: 1200 tur (12 s), ariza 200. turda, 32 yuva; secilen kural: son 20 cagrinin 0.5'si basarisizsa ac, 100 tur kesik kal

kosum                       takip yanit  takip yuvasiz     olay yanit       olay red      olay hata  yapilan cagri  olay yuva-tur
saglikli, kesicisiz                5000              0           1135              0             31           1166           7492
saglikli, kesicili                 5000              0           1135              0             31           1166           7492
kismi, kesicisiz                   5000              0           1021              0            145           1166           6637
kismi, kesicili                    5000              0           1021              0            145           1166           6637
yavaslama, kesicisiz               4329            671            190              0            826           1016          19312
yavaslama, kesicili                5000              0            190            953             23            213           1646
durma, kesicisiz                   5000              0            190              0            976           1166           4144
durma, kesicili                    5000              0            190            953             23            213           1285

arizasiz gunun bedeli: 1166 cagrinin hepsinde kesici sorgulanir ve 20 kayitlik pencere tutulur; 0 yanlis acilma, 0 reddedilen gecerli olay; kismi arizada 0 acilma ve olay yanit 1021 -> 1021 (0 basarili olabilecek olay reddedildi)
arizali gunun kazanci (yavaslama): takip yuvasiz 671 -> 0, olay yuva-tur 19312 -> 1646 (%91.48 az), bozuk bagimliliga cagri 1016 -> 213
ayni kazanc durmada: takip yuvasiz 0 -> 0, olay yuva-tur 4144 -> 1285, cagri 1166 -> 213
AY3'un 10 dakikasina olcek: yavaslamada tasarruf edilen cagri 48180, kurtarilan takip istegi 40260

kural             kip         algilama turu algilamaya kadar yuva-tur  acilma  reddedilen gecerli olay
ardisik 5         saglikli                -                         -       0                        0
ardisik 5         kismi                   -                         -       0                        0
ardisik 5         yavaslama               4                       110      10                        -
ardisik 5         durma                   4                        15      10                        -
oran 0,50 / 20    saglikli                -                         -       0                        0
oran 0,50 / 20    kismi                   -                         -       0                        0
oran 0,50 / 20    yavaslama               9                       220      10                        -
oran 0,50 / 20    durma                   9                        30      10                        -
oran 0,10 / 20    saglikli                -                         -       4                      386
oran 0,10 / 20    kismi                  88                       117       9                      698
oran 0,10 / 20    yavaslama              67                        22      11                        -
oran 0,10 / 20    durma                  67                         3      11                        -
duyarlilik: kesik suresi 100 yerine 200 tur olsaydi yavaslamada yapilan cagri 213 -> 208; oran 0,10 kuralinda arizasiz gunde reddedilen gecerli olay 386 -> 741
```

Bu sayılar **ölçüm** sınıfındadır ve tohuma bağlıdır; aynı tohum aynı tabloyu verir.

İlk iki satır kalıbın arızasız gündeki bedelini veriyor ve bedel şaşırtıcı derecede küçüktür.
Sağlıklı günde kesicili ile kesicisiz koşum **birbirinin aynıdır**: 5000 takip yanıtı, 1135 olay
yanıtı, 0 yanlış açılma, 0 reddedilen geçerli olay. Bedel sayılabilir ama küçüktür — kesici 1166
çağrının hepsinde sorgulanır ve bağımlılık başına 20 kayıtlık bir pencere tutar. **Doğru
boyutlandırılmış bir eşik arızasız günde görünmez olur.**

Üçüncü ve dördüncü satır kazancı veriyor. Yavaşlama kipinde kesicisiz koşumda 5000 takip isteğinin
671'i yuva bulamıyor — 01. dersin bulaşma tablosunun tur düzeyindeki karşılığı budur. Kesici
konduğunda bu sayı **0** oluyor: takip sorgusu, kendisiyle hiç ilgisi olmayan bir bağımlılığın
yavaşlamasından artık etkilenmiyor. Olay bacağının tuttuğu yuva-tur 19.312'den 1646'ya iniyor, yani
yüzde 91,48 azalıyor ve bozuk bağımlılığa yapılan çağrı 1016'dan 213'e düşüyor. AY3'ün 10
dakikalık yavaşlamasına ölçeklendiğinde bu, tasarruf edilen 48.180 çağrı ve kurtarılan 40.260 takip
isteği eder.

Beşinci ve altıncı satır kesicinin **neyi kurtarmadığını** gösteriyor. Durma kipinde kesicisiz
koşumda takip yuvasız isteği zaten 0'dır; hızlı hata yuvayı tutmadığı için bulaşma yoktur ve
kesicinin koruyacak bir şeyi kalmaz. Orada kazanç başka bir yerdedir: yapılan çağrı 1166'dan 213'e,
yuva-tur 4144'ten 1285'e iner. Duran bir bağımlılıkta kesici **bulaşmayı değil, boşa giden işi**
keser.

Bir satır da kalıbın kendi bedelini itiraf ediyor: kesicili yavaşlama koşumunda 953 olay
reddediliyor. Kesici olay akışını kurtarmıyor, onu **çevreliyor**. Reddedilen 953 durum olayı hâlâ
gerçek olaylardır ve bir yere gitmek zorundadır; onları nereye koyacağı bu kalıbın sorusu değildir.

#### Eşik Arıza Kipine Göre Seçilir

İkinci tablo üç eşik kuralını dört kipte koşturuyor ve tek bir eşiğin dört kipi birden
karşılayamayacağını gösteriyor.

**Ardışık başarısızlık sayısı en ucuz kuraldır ama kısmi arızayı hiç görmez.** Ardışık 5 kuralı
yavaşlamayı ve durmayı 4. turda yakalıyor, sağlıklı günde bir kez bile yanlış açmıyor — ama kısmi
arızada da hiç açmıyor. Nedeni aritmetiktir: sekizde bir başarısızlık oranında beş çağrının arka
arkaya başarısız olması ender bir olaydır. Kısmi arızada bu doğru davranıştır; çağrıların yedi
bölü sekizi hâlâ başarılıdır ve kesmek kazançtan çok kayıp getirir.

**Algılamanın gecikmesi değil, bedeli kipe göre değişiyor.** Ardışık 5 kuralında hem durma hem
yavaşlama 4. turda algılanıyor; eşzamanlı çağrılar beş başarısızlığı aynı hızda biriktiriyor. Ama
algılamaya kadar tutulan yuva-tur durmada 15, yavaşlamada 110 — **7,3 kat.** Oran 0,50 kuralında
fark daha da açılıyor: 30'a karşı 220. Eşik sayıyla değil, o sayının kaç yuva-tura mal olduğuyla
seçilmelidir; yavaş bir bağımlılıkta yirmi çağrı beklemek yüz yirmi çağrı beklemeye denktir.

#### Yanlış Açılmanın Bedeli

Üçüncü kural bunu tersinden gösteriyor. Oran 0,10 eşiği yavaşlamayı ve durmayı çok daha ucuza
yakalıyor — algılamaya kadar yalnız 22 ve 3 yuva-tur — ve kısmi arızayı da 88. turda görüyor. Bedeli
öteki iki sütundadır.

Sağlıklı günde bu kural 4 kez açılıyor ve **386 geçerli olayı reddediyor**; bağımlılıkta hiçbir
sorun yokken. Kısmi arızada 9 kez açılıyor ve 698 geçerli olayı reddediyor — oysa o olayların
başarılı olma olasılığı sekizde yediydi. **Yanlış açılma sağlıklı bir bağımlılığı kesmektir ve
bedeli reddedilen geçerli istektir.**

Duyarlılık satırı bu bedelin kesik süresine bağlı olduğunu söylüyor: kesik 100 turdan 200 tura
çıkarılsaydı yavaşlamada yapılan çağrı 213'ten 208'e inerdi — neredeyse hiç kazanç — ama sağlıklı
günde reddedilen geçerli olay 386'dan 741'e çıkardı. **Kesik süresini uzatmak arızalı günde az
kazandırır, arızasız günde çok kaybettirir**, çünkü kazanç arızanın süresine değil kesicinin bir
kez açılmasına bağlıdır, kayıp ise doğrudan kesik süresiyle çarpılır.

#### Özet

- Devre kesici bir bağımlılığı devreden çıkarır; kapalı, açık ve yarı açık durumları Uygulama
  Mimarisi kursunda kuruldu ve burada tekrarlanmaz. Servisler arasında koruduğu şey çağıranın
  paylaşılan yuva havuzudur.
- Doğru boyutlandırılmış eşik arızasız günde görünmezdir: sağlıklı günde kesicili ve kesicisiz koşum
  aynı sayıları veriyor, 0 yanlış açılma. Bedel 1166 çağrının her birinde yapılan bir denetim ve
  bağımlılık başına 20 kayıtlık penceredir.
- Yavaşlamada kazanç büyüktür: yuva bulamayan takip isteği 671 → 0, olay bacağının yuva-turu 19.312
  → 1646 (%91,48 az), bozuk bağımlılığa çağrı 1016 → 213. AY3'ün 10 dakikasında 48.180 çağrı
  tasarrufu ve 40.260 kurtarılan takip isteği.
- Durmada bulaşma zaten yoktur (takip yuvasız 0 → 0); oradaki kazanç boşa giden iştir: çağrı 1166 →
  213, yuva-tur 4144 → 1285.
- Algılamanın bedeli kipe göre değişir, gecikmesi değil: ardışık 5 kuralı iki kipi de 4. turda
  yakalar ama algılamaya kadar tutulan yuva-tur durmada 15, yavaşlamada 110.
- Yanlış açılma sağlıklı bağımlılığı keser: oran 0,10 eşiği sağlıklı günde 386, kısmi arızada 698
  geçerli olayı reddeder; kesik süresi 200 tura çıkarılırsa sağlıklı gündeki kayıp 741'e çıkar,
  arızalı gündeki kazanç ise 213'ten 208'e ancak iner.

#### Sonraki Adım

Kesici bir sınır çizdi ama sınırın yeri dikkatle okunmalı: koruma **algılamadan sonra** başlıyor.
Oran 0,50 kuralında yavaşlama 9. turda algılanıyor ve o dokuz tur boyunca bozuk bağımlılık
paylaşılan havuzdan 220 yuva-tur çekiyor. Eşiği düşürmek bu payı küçültür ama yanlış açılmayı
büyütür; ikisi birden küçültülemez. Dahası kesici her bağımlılığa ayrı ayrı konur, oysa havuz
tektir: kesicisi olmayan ya da eşiğinin altında kalan bir yavaşlama havuzu yine tüketir ve komşu
akışı yine düşürür. O hâlde bir soru daha vardır — bulaşmayı algılamaya hiç bağlamadan kesmek
mümkün müdür. Sonraki ders havuzun kendisini böler: her akışa kendi yuvaları verilir, bir akışın
tüketebileceği kaynak baştan sınırlanır ve bunun arızasız günde ne kadara mal olduğu sayılır.

### Bölme Kalıbı

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/bolme-kalibi

Kaynak havuzunun akışlara göre ayrıştırılması: tek havuzda bir yavaş bağımlılığın bütün havuzu tüketmesiyle bölmeli düzenin aynı arıza senaryosunda karşılaştırılması, bölmenin komşu akışı algılamaya hiç bağlamadan koruması, bölmenin arızasız günde atıl kalan yuva ve düşen doluluk cinsinden bedeli ve bölme boyutunun iki gün arasındaki değiş tokuşu.

Devre kesici bulaşmayı kesti ama koruması algılamadan sonra başlıyordu: eşik dolana kadar bozuk
bağımlılık paylaşılan havuzdan yuva çekmeyi sürdürdü, oran 0,50 kuralında 220 yuva-tur. Eşiği
düşürmek bu payı küçültüyor ama yanlış açılmayı büyütüyordu. Bu dersin sorusu şudur: bulaşmayı
algılamaya hiç bağlamadan kesmek mümkün mü.

Mümkündür ve yolu havuzu bölmektir. **Bölme kalıbı** (bulkhead), çağıranın kaynaklarını akışlara ya
da bağımlılıklara göre ayrı havuzlara ayırmaktır; bir akış yalnız kendi havuzunu tüketebilir ve
tükettiğinde komşu akış hiçbir şey hissetmez. Adı gemi gövdesinin su geçirmez bölmelerinden gelir:
bir bölme dolduğunda gemi batmaz, o bölme dolmuş olur. Buradaki **bölme**, Kabuk Programlama
kursundaki dosya bölmeyle ve Trafik Katmanı kursundaki bölme kalanıyla aynı sözcüktür ama ayrı
kavramdır: burada bölünen şey **kaynak havuzudur**.

Kesiciden farkı tek cümleyle söylenebilir. Kesici bağımlılığın bozuk **olduğunu anlar** ve çağrıyı
durdurur; bölme hiçbir şey anlamaz, yalnız bozuk akışın tüketebileceği kaynağı baştan sınırlar.
Biri karar verir, öteki sınır koyar.

#### Aynı Havuz, İki Düzen

Aşağıdaki koşum yine bir **modeldir**. 01. dersin ağ geçidi yuva havuzu ele alınıyor; tek fark
varışların artık düzgün değil, tohumlu bir üreteçten çekilen **Poisson** varışları olmasıdır. Bunun
nedeni bölmenin bedelinin ancak dalgalı varışta görünmesidir: düzgün akışta her akış kendi payını
tam doldurur ve paylaşmanın bir kazancı yoktur.

Arıza senaryosu 01. dersteki senaryodur — taşıyıcı doğrulaması yavaşlıyor, olay bacağının tutuşu 6
turdan 22 tura çıkıyor, AY3'e göre ayda 3 kez ve 10 dakika sürüyor.

```js
// bolme/kosum.mjs — tek havuz ile bolmeli duzenin ayni ariza senaryosunda karsilastirilmasi.
// MODELDIR: tur soyut bir adim, varislar tohumlu bir uretecten Poisson, bagimliligin kipi parametre.
const TOPLAM = 32, CEVRIM = 100, T = 4000, BAS = 1000;   // AY2, AY1; 40 s kosum, ariza 10. saniyede
const TAKIP = 416.67, OLAY = 97.22;                      // K01: tepe okuma ve tepe yazma istek/s
const TUTUS = { takip: 4, olay: 6 }, YAVAS = 22;         // 01. ders: ag gecidinin bacak sureleri

function kosum({ bolme, kip }) {                         // bolme: null ise tek havuz
  let s = 20260801 % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const poisson = (lam) => { const L = Math.exp(-lam); let k = 0, p = 1;
    do { k += 1; p *= rast(); } while (p > L); return k - 1; };
  const havuz = bolme === null ? { ortak: TOPLAM } : { takip: bolme, olay: TOPLAM - bolme };
  const yer = Object.fromEntries(Object.keys(havuz).map((h) => [h, []]));   // dolu yuvalarin bitis turu
  const ad = (akis) => (bolme === null ? "ortak" : akis);
  const c = { takipYanit: 0, takipDusen: 0, olayYanit: 0, olayDusen: 0, atil: 0, doluTur: 0 };

  for (let t = 0; t < T; t += 1) {
    for (const h of Object.keys(havuz)) yer[h] = yer[h].filter((x) => x > t);
    c.doluTur += Object.values(yer).reduce((a, x) => a + x.length, 0);
    const gelen = [];
    for (let n = poisson(TAKIP / CEVRIM); n > 0; n -= 1) gelen.push("takip");
    for (let n = poisson(OLAY / CEVRIM); n > 0; n -= 1) gelen.push("olay");
    for (let i = gelen.length - 1; i > 0; i -= 1) {
      const j = Math.floor(rast() * (i + 1));
      [gelen[i], gelen[j]] = [gelen[j], gelen[i]];
    }
    for (const akis of gelen) {
      const h = ad(akis);
      const sure = akis === "olay" && kip === "yavaslama" && t >= BAS ? YAVAS : TUTUS[akis];
      if (yer[h].length < havuz[h]) { yer[h].push(t + sure); c[`${akis}Yanit`] += 1; continue; }
      c[`${akis}Dusen`] += 1;
      for (const o of Object.keys(havuz)) if (o !== h) c.atil += havuz[o] - yer[o].length;
    }
  }
  return c;
}

const b = (x, n = 2) => x.toFixed(n);
const OLCUT = ["takipYanit", "takipDusen", "olayYanit", "olayDusen", "atil"];
const BASLIK = ["takip yanit", "takip dusen", "olay yanit", "olay dusen", "atil yuva"];
console.log(`model: ${T} tur (${T / CEVRIM} s), ariza ${BAS}. turda, toplam ${TOPLAM} yuva; ` +
  `varislar Poisson (tohum 20260801), takip ${(TAKIP / CEVRIM).toFixed(4)} ve olay ${(OLAY / CEVRIM).toFixed(4)} varis/tur`);

console.log(`\n${"duzen".padEnd(22)}${"gun".padEnd(12)}` + BASLIK.map((x) => x.padStart(13)).join("") +
  `${"ortalama dolu yuva".padStart(20)}`);
const r = {};
for (const [ad, bolme] of [["tek havuz (32)", null], ["bolmeli (24/8)", 24]])
  for (const kip of ["saglikli", "yavaslama"]) {
    const k = kosum({ bolme, kip });
    r[`${ad}|${kip}`] = k;
    console.log(`${ad.padEnd(22)}${kip.padEnd(12)}` + OLCUT.map((x) => String(k[x]).padStart(13)).join("") +
      `${b(k.doluTur / T).padStart(20)}`);
  }

const ts = r["tek havuz (32)|saglikli"], bs = r["bolmeli (24/8)|saglikli"];
const ty = r["tek havuz (32)|yavaslama"], by = r["bolmeli (24/8)|yavaslama"];
const olcek = (600 * CEVRIM) / (T - BAS);          // AY3: 10 dakikalik arizaya olcekleme
console.log(`\narizasiz gunun bedeli: takip dusen ${ts.takipDusen} -> ${bs.takipDusen}, olay dusen ` +
  `${ts.olayDusen} -> ${bs.olayDusen}; ortalama dolu yuva ${b(ts.doluTur / T)} -> ${b(bs.doluTur / T)} ` +
  `(doluluk ${b(ts.doluTur / T / TOPLAM, 3)} -> ${b(bs.doluTur / T / TOPLAM, 3)}); atil yuva ${ts.atil} -> ${bs.atil}`);
console.log(`arizali gunun kazanci: takip dusen ${ty.takipDusen} -> ${by.takipDusen} ` +
  `(%${b((100 * (ty.takipDusen - by.takipDusen)) / ty.takipDusen, 1)} az), olay dusen ` +
  `${ty.olayDusen} -> ${by.olayDusen}; AY3'un 10 dakikasinda kurtarilan takip istegi ` +
  `${((ty.takipDusen - by.takipDusen) * olcek).toFixed(0)}`);

console.log(`\n${"takip/olay yuvasi".padEnd(20)}${"arizasiz takip dusen".padStart(21)}` +
  `${"arizasiz olay dusen".padStart(20)}${"yavaslamada takip dusen".padStart(24)}` +
  `${"yavaslamada olay dusen".padStart(23)}`);
for (const bolme of [null, 28, 24, 20, 16]) {
  const s = kosum({ bolme, kip: "saglikli" }), y = kosum({ bolme, kip: "yavaslama" });
  const etiket = bolme === null ? `tek havuz (${TOPLAM})` : `${bolme}/${TOPLAM - bolme}`;
  console.log(`${etiket.padEnd(20)}${String(s.takipDusen).padStart(21)}${String(s.olayDusen).padStart(20)}` +
    `${String(y.takipDusen).padStart(24)}${String(y.olayDusen).padStart(23)}`);
}
const g36 = kosum({ bolme: 27, kip: "saglikli" });
console.log(`duyarlilik: 24/8 yerine 27/5 olsaydi arizasiz gunde takip dusen ${bs.takipDusen} -> ` +
  `${g36.takipDusen}, olay dusen ${bs.olayDusen} -> ${g36.olayDusen}; olay bolmesi ` +
  `${b(((OLAY / CEVRIM) * TUTUS.olay) / 8, 3)} dolulukta calisirken 5 yuvada ` +
  `${b(((OLAY / CEVRIM) * TUTUS.olay) / 5, 3)} olur`);
```

```
model: 4000 tur (40 s), ariza 1000. turda, toplam 32 yuva; varislar Poisson (tohum 20260801), takip 4.1667 ve olay 0.9722 varis/tur

duzen                 gun           takip yanit  takip dusen   olay yanit   olay dusen    atil yuva  ortalama dolu yuva
tek havuz (32)        saglikli            16542           78         3931           27            0               17.31
tek havuz (32)        yavaslama           13966         2654         3358          600            0               24.00
bolmeli (24/8)        saglikli            16448          172         3552          406         4239               16.77
bolmeli (24/8)        yavaslama           16448          172         1947         2011        19196               18.90

arizasiz gunun bedeli: takip dusen 78 -> 172, olay dusen 27 -> 406; ortalama dolu yuva 17.31 -> 16.77 (doluluk 0.541 -> 0.524); atil yuva 0 -> 4239
arizali gunun kazanci: takip dusen 2654 -> 172 (%93.5 az), olay dusen 600 -> 2011; AY3'un 10 dakikasinda kurtarilan takip istegi 49640

takip/olay yuvasi    arizasiz takip dusen arizasiz olay dusen yavaslamada takip dusen yavaslamada olay dusen
tek havuz (32)                         78                  27                    2654                    600
28/4                                   11                1754                      11                   2876
24/8                                  172                 406                     172                   2011
20/12                                 868                  37                     868                   1416
16/16                                2591                   0                    2591                    942
duyarlilik: 24/8 yerine 27/5 olsaydi arizasiz gunde takip dusen 172 -> 26, olay dusen 406 -> 1303; olay bolmesi 0.729 dolulukta calisirken 5 yuvada 1.167 olur
```

Bu sayılar **ölçüm** sınıfındadır ve tohuma bağlıdır.

#### Bölme Arızalı Günü Değiştirmiyor

İlk tablonun okunması dördüncü satırdan başlamalı, çünkü orada bir sayı çifti tekrar ediyor.
Bölmeli düzende takip sorgusunun düşen istek sayısı sağlıklı günde **172**, yavaşlama gününde de
**172**. Aynı sayı. Bağımlılık yavaşlasa da yavaşlamasa da takip akışı için hiçbir şey değişmiyor —
çünkü olay akışının tüketebileceği yuva sayısı sekizle sınırlıdır ve o sekiz yuva takip akışının
yirmi dördüne hiçbir koşulda dokunamaz.

Tek havuzda ise aynı arıza takip sorgusunun 2654 isteğini düşürüyor. Bölme bunu 172'ye indiriyor:
yüzde 93,5 az. AY3'ün 10 dakikalık yavaşlamasına ölçeklendiğinde 49.640 kurtarılan takip isteği
eder. Ve bu koruma **hiçbir algılamaya bağlı değildir**; kesicinin dokuz turluk algılama penceresi
burada yoktur, çünkü karar verilmiyor.

Kalıbın ne yapmadığı da aynı satırda. Bölmeli düzende olay akışının düşen isteği 600'den 2011'e
**çıkıyor**. Bölme olay akışını kurtarmıyor, tersine daha erken boğuyor; kurtardığı şey komşudur.
Kalıbın adı bunu zaten söylüyor — su alan bölme dolmaya devam eder.

#### Arızasız Günün Bedeli: Kaybedilen Paylaşım

İlk iki satır bedeli veriyor ve bedel küçük değildir. Sağlıklı günde tek havuz 78 takip ve 27 olay
isteği düşürüyor; toplam 105. Aynı gün bölmeli düzende 172 takip ve 406 olay isteği düşüyor; toplam
578. **Hiçbir arıza yokken bölme, düşen istek sayısını 5,5 katına çıkarıyor.**

Nedeni `atil yuva` sütunundadır. Bölmeli düzende bir istek düştüğünde öteki bölmede boş duran yuva
sayısı toplanıyor ve sağlıklı günde bu toplam 4239 ediyor: 4239 kez bir istek, komşu bölmede boş
yuva dururken reddedildi. Tek havuzda bu sayı tanımı gereği sıfırdır, çünkü boş yuva kimin olduğuna
bakmaz. Ortalama dolu yuva 17,31'den 16,77'ye, doluluk 0,541'den 0,524'e iniyor — aynı işi daha az
kaynakla değil, aynı kaynağı daha az kullanarak yapıyor.

Kaybedilen şeyin adı **paylaşımdır**: dalgalı iki akış tek havuzu paylaştığında birinin tepesi
ötekinin çukuruyla örtüşür ve toplam tepe, tepelerin toplamından küçük olur. Bölme bu örtüşmeyi
yasaklar. Arızasız günün bedeli budur ve doğrudan ölçülebilir: 94 fazladan düşen takip isteği, 379
fazladan düşen olay isteği, 0,017 düşen doluluk.

#### Bölme Boyutu İki Günü Birbirine Karşı Koyuyor

İkinci tablo boyut seçimini gösteriyor ve seçimin tek bir doğrusu olmadığını.

28/4 bölmesi takip akışını neredeyse kusursuz koruyor: yavaşlamada yalnız 11 istek düşüyor, tek
havuzun 2654'üne karşı. Bedeli arızasız gündedir — olay akışının dört yuvası yetmiyor ve sağlıklı
günde 1754 olay düşüyor. 16/16 bölmesi tersini yapıyor: olay akışı arızasız günde hiç düşmüyor,
buna karşılık takip akışı 2591 istek kaybediyor, yani tek havuzdaki arıza günü kadar. **Bölme
yanlış boyutlandırıldığında arızasız günde arızalı gün kadar zarar verir.**

24/8 ikisinin arasındadır ve seçilme gerekçesi ölçülebilir: olay akışının ortalama yükü 0,9722
varış/tur çarpı 6 tur, yani 5,83 yuva; sekiz yuva bunun 1,37 katıdır. Duyarlılık satırı payın
daraltılmasının bedelini veriyor — 27/5'te takip düşen 172'den 26'ya iner ama olay düşen 406'dan
1303'e çıkar, çünkü olay bölmesinin doluluğu 0,729'dan 1,167'ye, yani kapasitenin üstüne geçer.
**Bir bölme, kendi akışının olağan yükünü taşıyamayacak kadar küçültülürse arıza beklemeden
arızalanır.**

Bölme ile kesici birbirinin yerine geçmez. Bölme bulaşmayı algılamasız keser ama bozuk bağımlılığa
yapılan çağrıyı kesmez: bölmeli yavaşlama koşumunda olay akışı hâlâ bozuk bağımlılığı çağırıyor ve
kendi sekiz yuvasını tüketiyor. Kesici o çağrıları durdurur ama önce anlaması gerekir. İkisi ayrı
sayıyı oynatır — bölme komşunun düşen isteğini, kesici bozuk bağımlılığa yapılan çağrıyı.

#### Özet

- Bölme kalıbı çağıranın kaynak havuzunu akışlara göre ayırır; bir akış yalnız kendi havuzunu
  tüketebilir. Kesiciden farkı karar vermemesidir — sınır baştan konur, algılama gerekmez.
- Bölme arızalı günü komşu akış için görünmez kılıyor: bölmeli düzende takip sorgusunun düşen isteği
  sağlıklı günde de yavaşlama gününde de 172. Tek havuzda aynı arıza 2654 istek düşürüyor; kazanç
  yüzde 93,5, AY3'ün 10 dakikasında 49.640 istek.
- Bölme bozuk akışı kurtarmaz, daha erken boğar: olay akışının düşen isteği 600'den 2011'e çıkıyor.
- Arızasız günün bedeli kaybedilen paylaşımdır: düşen istek 105'ten 578'e (5,5 kat), doluluk
  0,541'den 0,524'e; 4239 kez bir istek komşu bölmede boş yuva dururken reddediliyor.
- Boyut iki günü birbirine karşı koyar: 28/4 yavaşlamada yalnız 11 takip isteği düşürür ama arızasız
  günde 1754 olay isteği; 16/16 olay akışını hiç düşürmez ama arızasız günde 2591 takip isteği
  kaybettirir.
- Bölme kendi akışının olağan yükünü taşımalıdır: olay akışı 5,83 yuva ister, 8 yuva bunun 1,37
  katıdır; 5 yuvada doluluk 1,167 olur ve bölme arıza olmadan arızalanır.

#### Sonraki Adım

Bölme ile kesici birlikte bir sınır çiziyor: bozuk bağımlılık kendi bölmesinde kalıyor ve bir süre
sonra hiç çağrılmıyor. İkisi de aynı varsayımın üstünde duruyor — başarısız olan çağrı **bir kez**
yapılıyor. Oysa gerçek bir çağıran başarısızlığı öyle karşılamaz; yeniden dener, çünkü hataların
çoğu geçicidir ve ikinci deneme çoğu zaman başarılı olur. Yeniden deneme bu iki kalıbın ölçtüğü her
şeyi değiştirir: bölmedeki yuvalar daha hızlı tükenir, kesicinin penceresine daha çok başarısızlık
düşer ve en önemlisi bozuk bağımlılık, kendisini zaten zorlayan sistemden daha çok istek alır.
Sonraki ders bu çarpanı ölçer: zincirin her katmanı denerse bağımlılığa varan istek kaça katlanır,
fırtına arızayı nasıl uzatır ve deneme hakkı zincirin hangi katmanına verilmelidir.

### Yeniden Deneme ve Fırtına Riski

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/yeniden-deneme-ve-firtina-riski

Yeniden denemenin çağrı çarpanı altında fırtınaya dönüşmesi: zincirin her katmanı denediğinde bozuk bağımlılığa varan çağrının kaç katına çıktığının ölçülmesi, aritmetik üst sınır ile geri çekilmenin altında gözlenen çarpanın ayrılması, çarpanın kesintide izne ve bozulmada başarısızlık oranına bağlanması ve deneme bütçesinin zincire dağıtılarak fırtınanın kesilmesi.

Bölme ile devre kesici bulaşmayı çevreledi ama ikisi de aynı varsayımın üstünde duruyordu:
başarısız olan çağrı bir kez yapılıyor. Gerçek bir çağıran öyle davranmaz. Hataların çoğu
geçicidir, ikinci deneme çoğu zaman başarılıdır ve bu yüzden hemen her katmana yeniden deneme
konur. Bu dersin sorusu, o kararın **bozuk bağımlılık üzerinde** ne yaptığıdır.

Yeniden deneme kararı, üstel geri çekilme, tavan, tam sarsıntı ve deneme bütçesi Uygulama Mimarisi
kursunda kuruldu ve ölçüldü; Eşzamansız İşleme kursu geri çekilme çizelgelerini ölçtü. Buradaki
koşumların hepsinde geri çekilme ve tam sarsıntı açıktır ve tohumu sabittir — böylece
karşılaştırmayı **yalnız çarpan** belirler. Sarsıntı aritmetiği yeniden hesaplanmaz.

Ölçülecek şey başkadır. Zincir üç katmanlıdır: ağ geçidi olay ucunu, olay ucu durum deposunu
çağırır. Her katman kendi başına makul bir karar verir — "başarısız olursa üç kez dene" — ve kimse
öteki katmanın da denediğini bilmez. Sonuç çarpılır: üç katman üçer kez denerse en dipteki
bağımlılık tek bir dış istek için yirmi yedi çağrı görebilir. Buna **yeniden deneme fırtınası**
denir ve tanımı gereği en kötü anda olur.

#### İki Arıza Profili

Aşağıdaki koşum bir **modeldir**: tur soyut bir adım, varışlar tohumlu bir üreteçten Poisson,
bağımlılığın kapasitesi tur başına çağrı sayısı. Gerçek küme, kuyruk ya da kaos aracı kurulmaz.

**AY6 — bağımlılığın olağan kapasitesi tur başına 6 çağrı (600 istek/s).** Gerekçe: K01'in tepe
yazma hızı 97,22 istek/s, yani tur başına 0,9722 çağrı; altı katlık pay dalgalı varışta taşmayı
seyrekleştirir. Duyarlılığı aşağıda deneme bütçesiyle birlikte verilir.

Arıza iki profille koşuluyor, çünkü çarpan ikisinde başka türlü davranıyor. **Kesinti:** bağımlılık
bir saniye boyunca hiçbir çağrıyı karşılamıyor (kapasite 0) — 01. dersin durma kipi. **Bozulma:**
on saniye boyunca kapasitesi altıda bire iniyor (kapasite 1) — çağrıların bir bölümü hâlâ başarılı.

```js
// firtina/kosum.mjs — cagri carpani altinda yeniden deneme firtinasi. MODELDIR: tur soyut bir adim,
// varislar tohumlu Poisson, geri cekilme ustel ve tam sarsintili (aritmetigi M14/K06'da olculdu).
const CEVRIM = 100, T = 4000, BAS = 500;        // AY1: 1 tur = 10 ms; 40 s kosum, ariza 5. saniyede
const OLAY = 97.22, OLAGAN = 6;                 // K01 tepe yazma istek/s; AY6: olagan kapasite cagri/tur
const TABAN = 2, TAVAN = 32, SEYREK = 0.025;    // geri cekilme taban/tavani (tur); AY4
const SENARYO = {                               // pencere suresi ve pencere boyunca kalan kapasite
  saglikli: { sure: 0, kapasite: OLAGAN },
  "kesinti (1 s)": { sure: 100, kapasite: 0 },
  "bozulma (10 s)": { sure: 1000, kapasite: 1 },
};

function kosum({ deneme, butce, senaryo }) {
  let s = 20260802 % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const poisson = (lam) => { const L = Math.exp(-lam); let k = 0, p = 1;
    do { k += 1; p *= rast(); } while (p > L); return k - 1; };
  const { sure, kapasite: bozuk } = SENARYO[senaryo];
  const izin = deneme.reduce((a, x) => a * x, 1);   // izin verilen deneme = katmanlarin carpimi
  const cizelge = new Map();
  const koy = (t, i) => { if (t < T) (cizelge.get(t) ?? cizelge.set(t, []).get(t)).push(i); };
  const c = { istek: 0, cagri: 0, birincil: 0, ek: 0, basarili: 0, dusen: 0, tepe: 0, pencereCagri: 0 };

  for (let t = 0; t < T; t += 1) {
    const pencerede = sure > 0 && t >= BAS && t < BAS + sure;
    const kapasite = pencerede ? bozuk : OLAGAN;
    for (let n = poisson(OLAY / CEVRIM); n > 0; n -= 1) { c.istek += 1; koy(t, { n: 0 }); }
    const bugun = cizelge.get(t) ?? [];
    c.cagri += bugun.length; c.tepe = Math.max(c.tepe, bugun.length);
    if (pencerede) c.pencereCagri += bugun.length;
    bugun.forEach((istek, i) => {
      if (istek.n === 0) c.birincil += 1; else c.ek += 1;
      if (i < kapasite && (sure > 0 || rast() >= SEYREK)) { c.basarili += 1; return; }
      const butceVar = butce === null || c.ek <= butce * c.birincil;
      if (istek.n + 1 >= izin || butceVar === false) { c.dusen += 1; return; }
      const ust = Math.min(TAVAN, TABAN * 2 ** istek.n);   // ustel geri cekilme + tam sarsinti
      koy(t + 1 + Math.floor(rast() * ust), { n: istek.n + 1 });
    });
    cizelge.delete(t);
  }
  return { ...c, izin, carpan: c.cagri / c.istek, pencereHiz: sure === 0 ? 0 : c.pencereCagri / sure };
}

const b = (x, n = 2) => x.toFixed(n);
const YAP = [                                    // zincir: ag gecidi -> olay ucu -> durum deposu
  ["denemesiz", [1, 1, 1], null],
  ["yalniz gecit (3)", [3, 1, 1], null],
  ["iki katman (3x3)", [3, 3, 1], null],
  ["uc katman (3x3x3)", [3, 3, 3], null],
  ["uc katman + butce 0,30", [3, 3, 3], 0.3],
];
console.log(`model: ${T} tur (${T / CEVRIM} s), ariza ${BAS}. turda; olagan kapasite ${OLAGAN} cagri/tur ` +
  `(${OLAGAN * CEVRIM} istek/s), olay varisi ${(OLAY / CEVRIM).toFixed(4)}/tur; tohum 20260802`);

const r = {};
for (const senaryo of Object.keys(SENARYO)) {
  const p = SENARYO[senaryo];
  console.log(`
-- ${senaryo}${p.sure === 0 ? " (AY4: 0,025 seyrek hata)"
    : `: ${p.sure} tur boyunca kapasite ${p.kapasite}`} --`);
  console.log(`${"yapilandirma".padEnd(25)}${"izin".padStart(6)}${"cagri".padStart(8)}${"carpan".padStart(9)}` +
    `${"tepe cagri/tur".padStart(16)}${"basarili".padStart(10)}${"dusen".padStart(8)}` +
    (p.sure === 0 ? "" : `${"pencerede cagri/tur".padStart(20)}${"olagan hizin kati".padStart(19)}`));
  for (const [ad, deneme, butce] of YAP) {
    const k = kosum({ deneme, butce, senaryo });
    r[`${ad}|${senaryo}`] = k;
    console.log(`${ad.padEnd(25)}${String(k.izin).padStart(6)}${String(k.cagri).padStart(8)}` +
      `${`x${b(k.carpan)}`.padStart(9)}${String(k.tepe).padStart(16)}${String(k.basarili).padStart(10)}` +
      `${String(k.dusen).padStart(8)}` + (p.sure === 0 ? ""
        : `${b(k.pencereHiz).padStart(20)}${`x${b(k.pencereHiz / (OLAY / CEVRIM), 1)}`.padStart(19)}`));
  }
}

const al = (ad, sen) => r[`${ad}|${sen}`];
const K = "kesinti (1 s)", B = "bozulma (10 s)";
const [s0, s27] = [al("denemesiz", "saglikli"), al("uc katman (3x3x3)", "saglikli")];
const [k0, k3, k9, k27, kb] = YAP.map(([ad]) => al(ad, K));
const [z0, z9, z27, zb] = [al("denemesiz", B), al("iki katman (3x3)", B),
  al("uc katman (3x3x3)", B), al("uc katman + butce 0,30", B)];
console.log(`
arizasiz gunun bedeli: cagri ${s0.cagri} -> ${s27.cagri} (carpan x${b(s27.carpan)}), ` +
  `bagimliliga varan ${b((s0.cagri / T) * CEVRIM)} -> ${b((s27.cagri / T) * CEVRIM)} istek/s; ` +
  `izin 1 ile 27 arasinda fark yok, cunku basarisizlik orani 0,025`);
console.log(`arizali gunun kazanci (kesinti): dusen istek ${k0.dusen} -> ${k3.dusen} -> ${k9.dusen} -> ` +
  `${k27.dusen}; basarili ${k0.basarili} -> ${k27.basarili}`);
console.log(`firtinanin buyumesi (kesinti): pencerede cagri/tur ${b(k0.pencereHiz)} -> ${b(k3.pencereHiz)} -> ` +
  `${b(k9.pencereHiz)} -> ${b(k27.pencereHiz)} = olagan hizin x${b(k27.pencereHiz / (OLAY / CEVRIM), 1)}'i; ` +
  `aritmetik ust sinir x${k27.izin}`);
console.log(`bozulmada carpan izne degil basarisizlik oranina bagli: izin 9 ve 27 ayni cagriyi veriyor ` +
  `(${z9.cagri} ve ${z27.cagri}), pencere hizi ${b(z27.pencereHiz)}`);
console.log(`butce 0,30 zincire dagitilinca: kesintide cagri ${k27.cagri} -> ${kb.cagri}, pencere hizi ` +
  `${b(k27.pencereHiz)} -> ${b(kb.pencereHiz)}, dusen ${k27.dusen} -> ${kb.dusen}; bozulmada cagri ` +
  `${z27.cagri} -> ${zb.cagri}, dusen ${z0.dusen} -> ${z27.dusen} -> ${zb.dusen}`);
console.log(`kosumdan bagimsiz ust sinir: d katman r kez denerse carpan r^d; r=3 icin ` +
  `${[1, 2, 3, 4].map((d) => `d=${d} -> ${3 ** d}`).join(", ")}`);
const ESIK = 20;                                 // AY2: zaman asimi 20 tur = K01'in 200 ms'lik esigi
const enKotu = Array.from({ length: 27 }, (_, n) => 1 + Math.min(TAVAN, TABAN * 2 ** n))
  .reduce((a, x) => a + x, 0);
console.log(`27 denemenin en kotu toplam beklemesi ${enKotu} tur = ${enKotu / CEVRIM} s, K01'in ` +
  `${ESIK} turluk okuma esiginin ${b(enKotu / ESIK, 1)} kati`);
const dar = kosum({ deneme: [3, 3, 3], butce: 0.1, senaryo: K });
console.log(`duyarlilik: butce 0,30 yerine 0,10 olsaydi kesintide cagri ${kb.cagri} -> ${dar.cagri}, ` +
  `pencere hizi ${b(kb.pencereHiz)} -> ${b(dar.pencereHiz)}, dusen ${kb.dusen} -> ${dar.dusen}`);
```

```
model: 4000 tur (40 s), ariza 500. turda; olagan kapasite 6 cagri/tur (600 istek/s), olay varisi 0.9722/tur; tohum 20260802

-- saglikli (AY4: 0,025 seyrek hata) --
yapilandirma               izin   cagri   carpan  tepe cagri/tur  basarili   dusen
denemesiz                     1    3832    x1.00               6      3736      96
yalniz gecit (3)              3    3953    x1.03               6      3851       0
iki katman (3x3)              9    3953    x1.03               6      3851       0
uc katman (3x3x3)            27    3953    x1.03               6      3851       0
uc katman + butce 0,30       27    3953    x1.03               6      3851       0

-- kesinti (1 s): 100 tur boyunca kapasite 0 --
yapilandirma               izin   cagri   carpan  tepe cagri/tur  basarili   dusen pencerede cagri/tur  olagan hizin kati
denemesiz                     1    3855    x1.00               5      3775      80                0.80               x0.8
yalniz gecit (3)              3    4071    x1.05               8      3782      94                2.89               x3.0
iki katman (3x3)              9    4435    x1.15              13      3850      20                5.77               x5.9
uc katman (3x3x3)            27    4523    x1.17              17      3870       0                6.24               x6.4
uc katman + butce 0,30       27    4065    x1.05              10      3777     103                2.88               x3.0

-- bozulma (10 s): 1000 tur boyunca kapasite 1 --
yapilandirma               izin   cagri   carpan  tepe cagri/tur  basarili   dusen pencerede cagri/tur  olagan hizin kati
denemesiz                     1    3855    x1.00               5      3534     321                0.95               x1.0
yalniz gecit (3)              3    4913    x1.28               8      3754      94                2.01               x2.1
iki katman (3x3)              9    5296    x1.39               9      3803       0                2.39               x2.5
uc katman (3x3x3)            27    5296    x1.39               9      3803       0                2.39               x2.5
uc katman + butce 0,30       27    4288    x1.11               7      3643     220                1.40               x1.4

arizasiz gunun bedeli: cagri 3832 -> 3953 (carpan x1.03), bagimliliga varan 95.80 -> 98.83 istek/s; izin 1 ile 27 arasinda fark yok, cunku basarisizlik orani 0,025
arizali gunun kazanci (kesinti): dusen istek 80 -> 94 -> 20 -> 0; basarili 3775 -> 3870
firtinanin buyumesi (kesinti): pencerede cagri/tur 0.80 -> 2.89 -> 5.77 -> 6.24 = olagan hizin x6.4'i; aritmetik ust sinir x27
bozulmada carpan izne degil basarisizlik oranina bagli: izin 9 ve 27 ayni cagriyi veriyor (5296 ve 5296), pencere hizi 2.39
butce 0,30 zincire dagitilinca: kesintide cagri 4523 -> 4065, pencere hizi 6.24 -> 2.88, dusen 0 -> 103; bozulmada cagri 5296 -> 4288, dusen 321 -> 0 -> 220
kosumdan bagimsiz ust sinir: d katman r kez denerse carpan r^d; r=3 icin d=1 -> 3, d=2 -> 9, d=3 -> 27, d=4 -> 81
27 denemenin en kotu toplam beklemesi 793 tur = 7.93 s, K01'in 20 turluk okuma esiginin 39.6 kati
duyarlilik: butce 0,30 yerine 0,10 olsaydi kesintide cagri 4065 -> 3926, pencere hizi 2.88 -> 1.54, dusen 103 -> 90
```

Bu sayılar **ölçüm** sınıfındadır ve tohuma bağlıdır.

#### Arızasız Günde Çarpan Uykudadır

İlk tablo kalıbın arızasız gündeki bedelini veriyor ve bedel küçüktür: çağrı 3832'den 3953'e
çıkıyor, çarpan 1,03, bağımlılığa varan hız 95,80'den 98,83 istek/s'ye. Karşılığında düşen istek
96'dan 0'a iniyor — arızasız günde yeniden deneme, seyrek zaman aşımlarını yüzde üçlük bir bedelle
tamamen soğuruyor.

Asıl önemli olan tablonun **hiç değişmeyen** sütunudur. İzin verilen deneme 1'den 27'ye çıkarken
çağrı sayısı sabit kalıyor. Nedeni aritmetiktir: başarısızlık oranı 0,025 iken bir isteğin üçüncü
denemeye ihtiyaç duyma olasılığı binde birin altındadır, dolayısıyla yirmi yedilik izin hiç
kullanılmaz. **Çağrı çarpanı arızasız günde uykudadır; onu uyandıran şey başarısızlık oranıdır.**
Bir zincirin fazla deneme hakkı taşıdığı, olağan koşulda hiçbir ölçütte görünmez.

#### Kesintide Fırtına Katmanla Büyüyor

İkinci tablo uyanışı gösteriyor. Bağımlılık bir saniye boyunca hiçbir çağrıyı karşılamazken pencere
içindeki çağrı hızı katman eklendikçe büyüyor: denemesiz 0,80, tek katmanda 2,89, iki katmanda
5,77, üç katmanda 6,24 çağrı/tur. Son sayı olağan hızın **6,4 katıdır** ve düşmüş bir bağımlılığa
gidiyor.

Aritmetik üst sınır ile gözlenen çarpan ayrılmalıdır. Üç katman üçer denemeyle 27'lik izin verir;
gözlenen 6,4'tür. Farkı geri çekilme yaratıyor — denemeler zamana yayıldığı için hepsi pencereye
sığmaz. **Üst sınır tasarımın taşıdığı risktir, gözlenen çarpan o riskin bu parametrelerde
gerçekleşen payıdır.** Üst sınır koşumdan bağımsızdır: derinlik dörde çıkarsa 81.

Tablo çağıran tarafındaki kazancı da veriyor ve kazanç gerçektir: düşen istek denemesiz koşumda 80,
üç katmanlı koşumda **0**. Geri çekilme denemeleri pencerenin ötesine yaydığı için, yeterli deneme
hakkı olan her istek sonunda başarılı oluyor.

İki satır arasında ters giden bir şey de var. Tek katmanlı koşumda düşen istek 94, yani denemesiz
koşumun 80'inden **fazla**. Nedeni tepe sütununda: fırtına pencereden sonra tur başına 8 çağrıya
çıkıyor ve bu, olağan kapasite olan 6'nın üstündedir. Üç deneme hakkı, kesinti bittikten sonraki bu
ikinci dalgayı atlatmaya yetmiyor. **Yetersiz deneme hakkı, hiç denememekten kötü olabilir:** yükü
büyütür ama isteği kurtarmaz.

#### Bozulmada Çarpanı İzin Değil Başarısızlık Oranı Belirliyor

Üçüncü tablo aynı yapılandırmaları kapasitenin sıfıra değil bire indiği bir profilde koşuyor ve
sıralama değişiyor. İki katman ile üç katman **aynı sayıyı** veriyor: 5296 çağrı, pencerede 2,39
çağrı/tur. İzin 9'dan 27'ye çıkmasına rağmen hiçbir şey değişmiyor.

Nedeni ikinci tablodakinin tersidir. Kapasite bir olduğu için çağrıların bir bölümü hâlâ başarılı
oluyor; bir isteğin dokuz denemeyi tüketecek kadar üst üste başarısız olması ender bir olaydır.
Çarpanı belirleyen şey izin değil, **denemenin başarısızlık olasılığıdır.** Kural şöyle
yazılabilir: izin bir üst sınır koyar, gerçekleşen çarpanı arıza kipi seçer. Tam kesinti izni
sonuna kadar kullandırır, kısmi bozulma kullandırmaz.

Bozulmada çarpanın 2,5 kata çıkması yine de küçük değildir: kapasitesi altıda birine düşmüş bir
bağımlılık, kendisini zorlayan sistemden iki buçuk kat istek alıyor. **Bozulmayı uzatan budur.**

#### Deneme Bütçesi Zincire Dağıtılır

Son satır çözümü veriyor ve çözüm katman katman deneme sayısını kısmak değildir; her katmanın makul
bir sayı seçtiği ve toplamın çarpıldığı zaten görüldü. **Deneme bütçesi**, ek denemelerin birincil
çağrılara oranına bir tavan koyar ve o tavan zincirin tamamında geçerlidir.

Bütçe 0,30'a bağlandığında kesintide pencere hızı 6,24'ten 2,88 çağrı/tura, yani olağan hızın 3,0
katına iniyor; toplam çağrı 4523'ten 4065'e düşüyor. Bozulmada pencere hızı 2,39'dan 1,40'a,
toplam çağrı 5296'dan 4288'e iniyor. Bedeli açıktır: kesintide düşen istek 0'dan 103'e, bozulmada
0'dan 220'ye çıkıyor. **Bütçe, çağıranın kurtardığı isteğin bir bölümünü bağımlılığın nefes alması
için geri verir.**

Duyarlılık satırı bütçenin ne kadar sıkılabileceğini gösteriyor: 0,10'da kesintide pencere hızı
1,54'e iniyor ve düşen istek 103'ten 90'a **düşüyor** — daha sıkı bütçe burada iki tarafı birden
iyileştiriyor, çünkü küçülen fırtına pencere sonrası ikinci dalgayı da küçültüyor. Bütçenin doğru
değeri, arızanın kaç isteği kurtardığından çok fırtınanın kaç isteği ezdiğine bağlıdır.

#### Özet

- Zincirin her katmanı kendi başına yeniden deneme koyar ve izinler çarpılır: üç katman üçer
  denemede 27'lik bir üst sınır verir; d katman r denemede üst sınır r^d'dir ve d=4'te 81 olur.
- Arızasız günde çarpan uykudadır: izin 1'den 27'ye çıkarken çağrı sayısı değişmiyor, çarpan 1,03
  ve düşen istek 96'dan 0'a iniyor. Fazla deneme hakkı olağan koşulda hiçbir ölçütte görünmez.
- Tam kesintide fırtına katmanla büyüyor: pencerede çağrı hızı 0,80 → 2,89 → 5,77 → 6,24 çağrı/tur,
  olağan hızın 6,4 katı. Gözlenen çarpan aritmetik üst sınırın (27) altındadır, çünkü geri çekilme
  denemeleri zamana yayar.
- Yetersiz deneme hakkı hiç denememekten kötü olabilir: tek katmanlı koşumda düşen istek 94, oysa
  denemesiz koşumda 80; fırtına pencere sonrası tepeyi olağan kapasitenin üstüne, 8 çağrı/tura taşır.
- Kısmi bozulmada çarpanı izin değil başarısızlık oranı belirliyor: izin 9 ile 27 aynı sonucu
  veriyor (5296 çağrı, 2,39 çağrı/tur), çünkü hiçbir istek dokuz denemeyi tüketmiyor.
- Deneme bütçesi zincirin tamamına konur: 0,30'da kesinti fırtınası 6,24'ten 2,88 çağrı/tura,
  bozulma 2,39'dan 1,40'a iner; bedeli kesintide 103, bozulmada 220 düşen istektir.

#### Sonraki Adım

Bütün bu ölçümler bir sayıyı sabit tuttu: denemeler arasındaki bekleme. Oysa bekleme ile deneme
hakkı tek başına seçilemez, çünkü çarpımları çağıranın **ne kadar bekleyeceğini** belirler. Son
satır bunu veriyor: yirmi yedi deneme, tavanı otuz iki tur olan bir geri çekilmeyle bir isteği en
kötü durumda 793 tur, yani 7,93 saniye ayakta tutar — K01'in yirmi turluk okuma eşiğinin 39,6 katı.
Yani deneme politikasının gerçek sınırı deneme sayısında değil, çağıranın elindeki süredir; ve o
süre bu derste hiç bütçelenmedi. Sonraki ders onu ele alır ve zincir boyunca dağıtır: uçtan uca
eşik hangi adıma ne kadar pay bırakır, kalan pay alt çağrılara nasıl bölünür ve yavaşlayan bir
bağımlılıkta bütçe tükendiğinde iptal edilen iş nasıl sayılır.

### Zaman Aşımı Bütçeleri

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/zaman-asimi-butceleri

Yavaşlayan bir bağımlılıkta bütçenin nasıl tükendiği: kola kalan payın ardışık alt çağrılara açgözlü, eşit ve ağırlıklı bölüştürülmesi, açgözlü dağıtımın sağlam adımı suçlu göstermesi, çağıranın tuttuğu yuva ile bağımlılıkta terk edilen işin ayrı ayrı sayılması ve sıkı bölüştürmenin ancak iptal sinyaliyle birlikte kazanç yazması.

Yeniden deneme politikası artık kararlaştırılmış durumda: kaç kez denenecek, denemeler arasında ne
kadar beklenecek, sarsıntının genişliği ne olacak. Politikanın açıkta bıraktığı tek bir sayı var ve
o sayı politikanın kendisinden daha belirleyici — çağıran, vazgeçmeden önce toplam ne kadar
bekleyecek. Bu süre konmadıkça geri çekilme bir sınıra doğru değil, boşluğa doğru büyür.

Uygulama Katmanı ve Servis Etkileşimi kursu bu sürenin bir **bütçe** olduğunu kurdu: uçtan uca
eşik zincirin adımlarına bölüştürülür, kalan süre çağrıyla birlikte geçirilir ve deneme sayısı
bütçeyi çarpar. O hesap burada girdidir, tekrarlanmaz. Bu dersin sorusu bir basamak sonrasıdır.
Zincirdeki bir adım **yavaşladığında** bütçe nerede tükenir, kalan pay alt çağrılara nasıl bölünür
ve çağıran vazgeçtikten sonra bağımlılığın hâlâ yaptığı iş ne kadardır.

#### Arıza Kipi

Zincir bu kursun ortak yapısından gelir. Takip sorgusu ağ geçidinden girer ve iki kolu paralel
çağırır. Teslimat operasyonu kolu kendi deposundan tek bir kayıt okur; ücretlendirme kolu **iki
kayıt** okur — önce tarife, sonra gönderinin ölçüsü — ve ücreti ikisinden hesaplar. Uygulama
Katmanı kursu bir dış istek için dört adım çağrısı saymıştı; ücretlendirme kolunun depo basamağı
iki ardışık okumaya ayrıldığında sayı beşe çıkar.

**AY10 — tarife deposu yavaşlıyor.** Durmuyor, yanlış yanıt vermiyor, ağ bölünmesi yaşamıyor;
yalnız yanıt süresi olağan altı milisaniyelik ortancasının onlarca katına çıkıyor. Süre **12
dakika**, sıklık **ayda bir kez**. Gerekçe: yavaşlama bir bakım penceresiyle ya da bir sorgu planı
değişikliğiyle başlar ve fark edilip geri alınana kadar sürer; on iki dakika, K01'in on dakikalık
kurtarma süresi varsayımının biraz üstündedir. Duyarlılığı aşağıda hesaplanmıştır. Bu varsayım
K01'in tablosuna eklenmez.

Yavaşlama, durmadan daha zor bir kiptir. Durmuş bir bağımlılık bağlantıyı hemen reddeder ve çağıran
bunu milisaniyenin altında öğrenir. Yavaşlayan bağımlılık hiçbir şeyi reddetmez, yalnız bekletir —
ve bekleme, hiçbir sınır konmadıysa çağıranın kaynağıyla ödenir. Bütçe bu beklemenin ne kadarının
kabul edileceğine karar veren tek mekanizmadır.

#### Kalan Payın Bölünmesi

Kola düşen pay bellidir: K01'in 200 milisaniyelik okuma eşiğinden Uygulama Katmanı kursunun U3
varsayımı olan 20 milisaniyelik ağ geçidi payı çıkınca 180 milisaniye kalır. Ücretlendirme kolu bu
180 milisaniyeyi iki ardışık okumaya dağıtmak zorundadır ve üç politika vardır.

**Açgözlü** dağıtım kalanın tamamını her çağrıya verir: ilk okuma 180 milisaniyeye kadar
bekleyebilir, ikincisi geriye ne kalırsa onu alır. **Eşit** dağıtım payı ikiye böler. **Ağırlıklı**
dağıtım payı olağan sürelerin oranında paylaştırır; tarife 6, ölçü 12 milisaniye olduğuna göre oran
bire ikidir.

Üçü de arızasız günde neredeyse aynı görünür, çünkü iki okuma da payının çok altında kalır. Ayrım,
bir okuma payını aştığı anda çıkar.

```js
// butce/zincir.mjs — takip sorgusu zincirinin MODELI. Mantiksal saat: adim sureleri bir
// donguden okunur, gercek zaman olculmez; servis, ag ya da depo kurulmaz.
export const K01 = { esik: 200, tepeOkuma: 416.67, tepeUc: 513.89, yanitBayt: 480 };
export const GECIT_PAYI = 20;                 // K03 servis-tasarimi/05, varsayim U3
export const ORTANCA = { teslimat: 8, tarife: 6, olcu: 12 };   // model parametresi (ms)

const D = (govde, kuyruk) => [...govde, ...govde, kuyruk];     // 16'da bir uzun kuyruk
export const REJIM = {                        // alt cagrinin suresi (ms), on altilik dongu
  arizasiz: {
    teslimat: D([8, 9, 8, 10, 8, 9, 8, 10], 40),
    tarife: D([6, 7, 6, 8, 6, 7, 6, 8], 80),
    olcu: D([12, 13, 12, 14, 12, 13, 12, 14], 100),
  },
  "tarife yavas": {                           // AY10: yalniz tarife deposu yavasliyor
    teslimat: D([8, 9, 8, 10, 8, 9, 8, 10], 40),
    tarife: D([150, 400, 220, 400, 180, 300, 260, 400], 400),
    olcu: D([12, 13, 12, 14, 12, 13, 12, 14], 100),
  },
};

// Kola kalan payin iki ardisik alt cagriya bolusturulmesi.
export function paylar(politika, kalan) {
  if (politika === "acgozlu") return [kalan, kalan];
  if (politika === "esit") return [kalan / 2, kalan / 2];
  const t = ORTANCA.tarife + ORTANCA.olcu;    // agirlikli: olagan surelerin orani
  return [(kalan * ORTANCA.tarife) / t, (kalan * ORTANCA.olcu) / t];
}

export function kosum({ rejim, politika, iptal, n = 48 }) {
  const R = K01.esik - GECIT_PAYI;            // kola kalan pay
  const s = { yanit: 0, dusen: 0, bosaIs: 0, toplamSure: 0,
    basarisiz: { teslimat: 0, tarife: 0, olcu: 0 }, uctanUca: [] };
  const imlec = { teslimat: 0, tarife: 0, olcu: 0 };
  const sure = (ad) => REJIM[rejim][ad][imlec[ad]++ % REJIM[rejim][ad].length];

  const cagir = (ad, zt) => {                 // tek alt cagri, zaman asimi zt
    if (zt <= 0) return { ok: false, gecen: 0 };
    const su = sure(ad);
    if (su <= zt) return { ok: true, gecen: su };
    if (iptal === false) s.bosaIs += su - zt; // cagiran vazgecti, bagimlilik calisiyor
    return { ok: false, gecen: zt };
  };

  for (let i = 0; i < n; i += 1) {
    const a = cagir("teslimat", R);           // teslimat-op kolu: tek depo cagrisi
    const p = paylar(politika, R);            // ucretlendirme kolu: iki ardisik kayit
    const b1 = cagir("tarife", Math.min(p[0], R));
    const b2 = cagir("olcu", Math.min(p[1], R - b1.gecen));
    for (const [ad, r] of [["teslimat", a], ["tarife", b1], ["olcu", b2]]) {
      if (r.ok === false) s.basarisiz[ad] += 1;
    }
    const gecen = GECIT_PAYI + Math.max(a.gecen, b1.gecen + b2.gecen);
    s.uctanUca.push(gecen);
    s.toplamSure += gecen;
    if (a.ok && b1.ok && b2.ok && gecen <= K01.esik) s.yanit += 1; else s.dusen += 1;
  }
  const sirali = [...s.uctanUca].sort((x, y) => x - y);
  return { ...s, ortanca: sirali[n >> 1], enKotu: sirali[n - 1], ortalama: s.toplamSure / n, n };
}
```

İki okuma da her istekte denenir; ücretlendirme kolu ikisinin sonucunu topladıktan sonra karar
verir. Bu ayrıntı ölçümün taşıyıcısıdır: ilk okuma bütçeyi yerse ikinci okuma bunu **kendi
başarısızlığı** olarak yaşar.

```js
// butce/kosum.mjs — uc bolusturme politikasinin iki gunde karsilastirilmasi
import { K01, GECIT_PAYI, ORTANCA, paylar, kosum } from "./zincir.mjs";

const R = K01.esik - GECIT_PAYI;
const POLITIKA = ["acgozlu", "esit", "agirlikli"];
const CAGRI = 5;                       // dis istek basina alt cagri: 2 kol + 1 + 2 kayit
const SON_TARIH_BAYT = 8;              // kalan sureyi tasiyan alan
const yuva = (ms) => (K01.tepeOkuma * ms) / 1000;   // L = lambda x W

console.log(`uctan uca esik ${K01.esik} ms (K01), gecit payi ${GECIT_PAYI} ms (K03/U3), kola kalan ${R} ms`);
console.log(`olagan sureler: teslimat ${ORTANCA.teslimat}, tarife ${ORTANCA.tarife}, olcu ${ORTANCA.olcu} ms`);
console.log(`${"politika".padEnd(11)}${"tarife payi(ms)".padStart(16)}${"olcu payi(ms)".padStart(15)}`);
for (const p of POLITIKA) {
  const [a, b] = paylar(p, R);
  console.log(`${p.padEnd(11)}${a.toFixed(1).padStart(16)}${b.toFixed(1).padStart(15)}`);
}

for (const rejim of ["arizasiz", "tarife yavas"]) {
  console.log(`\n-- ${rejim} (48 dis istek, iptal sinyali yok) --`);
  console.log(`${"politika".padEnd(11)}${"yanit".padStart(6)}${"dusen".padStart(6)}${"suc:tarife".padStart(11)}` +
    `${"suc:olcu".padStart(9)}${"ortanca".padStart(8)}${"en kotu".padStart(8)}${"ort.".padStart(7)}` +
    `${"tutulan yuva".padStart(13)}${"bosa is(ms)".padStart(12)}`);
  for (const p of POLITIKA) {
    const r = kosum({ rejim, politika: p, iptal: false });
    console.log(`${p.padEnd(11)}${String(r.yanit).padStart(6)}${String(r.dusen).padStart(6)}` +
      `${String(r.basarisiz.tarife).padStart(11)}${String(r.basarisiz.olcu).padStart(9)}` +
      `${String(r.ortanca).padStart(8)}${String(r.enKotu).padStart(8)}${r.ortalama.toFixed(1).padStart(7)}` +
      `${yuva(r.ortalama).toFixed(1).padStart(13)}${String(r.bosaIs).padStart(12)}`);
  }
}

console.log(`\n-- tarife yavas: sistemin mesgul tuttugu yuva (tepe okuma ${K01.tepeOkuma}/s) --`);
console.log(`${"politika".padEnd(11)}${"cagiran".padStart(9)}${"terk edilen".padStart(12)}` +
  `${"toplam(iptalsiz)".padStart(17)}${"toplam(iptalli)".padStart(16)}`);
for (const p of POLITIKA) {
  const r = kosum({ rejim: "tarife yavas", politika: p, iptal: false });
  const c = yuva(r.ortalama), t = yuva(r.bosaIs / r.n);
  console.log(`${p.padEnd(11)}${c.toFixed(1).padStart(9)}${t.toFixed(1).padStart(12)}` +
    `${(c + t).toFixed(1).padStart(17)}${c.toFixed(1).padStart(16)}`);
}

const bayt = K01.tepeUc * CAGRI * SON_TARIH_BAYT;
const a = kosum({ rejim: "arizasiz", politika: "acgozlu", iptal: false });
console.log(`\n-- arizasiz gunun bedeli (hesap) --`);
console.log(`son tarih alani ${SON_TARIH_BAYT} B x ${CAGRI} alt cagri = ${CAGRI * SON_TARIH_BAYT} B/istek,` +
  ` takip yanitinin (${K01.yanitBayt} B) %${((CAGRI * SON_TARIH_BAYT) / K01.yanitBayt * 100).toFixed(1)}`);
console.log(`tepe ucta ${K01.tepeUc} istek/s -> ${bayt.toFixed(2)} B/s = ${(bayt / 1024).toFixed(2)} KiB/s`);
for (const p of ["esit", "agirlikli"]) {
  const r = kosum({ rejim: "arizasiz", politika: p, iptal: false });
  const fark = r.dusen - a.dusen;
  console.log(`${p.padEnd(11)}: acgozluye gore ${fark}/${r.n} fazladan dusen istek` +
    ` = %${((fark / r.n) * 100).toFixed(2)} -> tepe okumada ${((K01.tepeOkuma * fark) / r.n).toFixed(2)} istek/s`);
}

console.log(`\n-- AY10'un duyarliligi: tarifenin yavas kaldigi sure --`);
console.log(`${"sure(dk)".padStart(9)}${"ayda".padStart(6)}${"aylik(dk)".padStart(11)}${"ariza payinin(28,2 dk)".padStart(23)}`);
for (const [dk, kez] of [[12, 1], [12, 2], [24, 1]]) {
  console.log(`${String(dk).padStart(9)}${String(kez).padStart(6)}${String(dk * kez).padStart(11)}` +
    `${`%${(((dk * kez) / 28.2) * 100).toFixed(1)}`.padStart(23)}`);
}
```

```
uctan uca esik 200 ms (K01), gecit payi 20 ms (K03/U3), kola kalan 180 ms
olagan sureler: teslimat 8, tarife 6, olcu 12 ms
politika    tarife payi(ms)  olcu payi(ms)
acgozlu               180.0          180.0
esit                   90.0           90.0
agirlikli              60.0          120.0

-- arizasiz (48 dis istek, iptal sinyali yok) --
politika    yanit dusen suc:tarife suc:olcu ortanca en kotu   ort. tutulan yuva bosa is(ms)
acgozlu        48     0          0        0      40     200   46.2         19.2           0
esit           46     2          0        2      40     190   45.8         19.1          20
agirlikli      46     2          2        0      40     180   45.3         18.9          40

-- tarife yavas (48 dis istek, iptal sinyali yok) --
politika    yanit dusen suc:tarife suc:olcu ortanca en kotu   ort. tutulan yuva bosa is(ms)
acgozlu         6    42         36       42     200     200  197.8         82.4        5540
esit            0    48         48        2     123     200  126.0         52.5        9700
agirlikli       0    48         48        0      93     180   96.4         40.2       11120

-- tarife yavas: sistemin mesgul tuttugu yuva (tepe okuma 416.67/s) --
politika     cagiran terk edilen toplam(iptalsiz) toplam(iptalli)
acgozlu         82.4        48.1            130.5            82.4
esit            52.5        84.2            136.7            52.5
agirlikli       40.2        96.5            136.7            40.2

-- arizasiz gunun bedeli (hesap) --
son tarih alani 8 B x 5 alt cagri = 40 B/istek, takip yanitinin (480 B) %8.3
tepe ucta 513.89 istek/s -> 20555.60 B/s = 20.07 KiB/s
esit       : acgozluye gore 2/48 fazladan dusen istek = %4.17 -> tepe okumada 17.36 istek/s
agirlikli  : acgozluye gore 2/48 fazladan dusen istek = %4.17 -> tepe okumada 17.36 istek/s

-- AY10'un duyarliligi: tarifenin yavas kaldigi sure --
 sure(dk)  ayda  aylik(dk) ariza payinin(28,2 dk)
       12     1         12                  %42.6
       12     2         24                  %85.1
       24     1         24                  %85.1
```

Bütün sayılar **hesap** sınıfındadır: belirlenimli bir süre dizisi üzerinde sayılmışlardır. Süre
birimi mantıksal bir saattir, ölçülmüş gecikme değildir; koşum makineden bağımsız aynı çıktıyı
verir.

#### Arızasız Günün Bedeli

Bütçenin iki kalemi arızasız günde de ödenir.

Birincisi taşınan alandır. Kalan süreyi çağrıyla birlikte geçirmek her alt çağrıya sekiz baytlık
bir alan ekler; beş alt çağrıda dış istek başına 40 bayt eder. Bu, K01'in 480 baytlık takip yanıtının
yüzde 8,3'üdür ve uçtaki tepe hızda saniyede 20,07 KiB'lik bir iç trafiktir. Küçük ama sıfır değil
ve zincir derinleştikçe doğrusal büyür.

İkincisi daha pahalıdır: **sıkı bölüştürme, sağlam istekleri keser.** Arızasız rejimde açgözlü
dağıtım kırk sekiz isteğin kırk sekizini yanıtlıyor. Eşit ve ağırlıklı dağıtım kırk altısını
yanıtlıyor; ikisi de iki isteği düşürüyor. Bunlar hiçbir arızanın olmadığı bir gündeki yanlış
pozitiflerdir — modelde on altıda bir gelen uzun kuyruk, adımın payını aşıyor. Oran yüzde 4,17;
K01'in tepe okuma hızında saniyede 17,36 istek eder. Hangi adımın kesildiği de politikaya bağlı:
eşit dağıtımda ölçü (payı 90, kuyruğu 100), ağırlıklı dağıtımda tarife (payı 60, kuyruğu 80).

Payı adımın kuyruğuna göre seçmek bu bedeli düşürür ama sıfırlamaz. Bütçe bölüştürmesi bir
kuyruk kesme kararıdır ve kesilen kuyruk her zaman gerçek isteklerden oluşur.

#### Arızalı Günde Ne Değişiyor

İkinci tablo AY10 altında koşuyor ve üç politikanın üç ayrı davranış ürettiğini gösteriyor.

**Açgözlü dağıtım altı isteği kurtarıyor.** Tarife kimi turlarda 150 ya da 180 milisaniyede
dönüyor; 180 milisaniyelik payla bunlar başarılı olur ve geriye ölçüye yetecek kadar kalır. Eşit ve
ağırlıklı dağıtımda aynı okumalar 90 ve 60 milisaniyede kesilir, kırk sekiz isteğin kırk sekizi
düşer. Bu, sıkı bölüştürmenin bedelinin arızalı günde de sürdüğü anlamına gelir — kurtarılabilir
istekler kurtarılmaz.

**Karşılığı uçtan uca sürede.** Açgözlü dağıtımda ortanca 200 milisaniye: her düşen istek bütçenin
tamamını yiyor. Eşit dağıtımda 123, ağırlıklı dağıtımda 93 milisaniye. Çağıran, aynı başarısızlığı
yarıdan kısa sürede öğreniyor. Bunun kaynak karşılığı `tutulan yuva` sütunudur: kuyruk kuramının
$L = \lambda W$ bağıntısıyla, K01'in 416,67 istek/s tepe okuma hızında açgözlü dağıtım 82,4,
ağırlıklı dağıtım 40,2 eşzamanlı çağıran yuvasını meşgul tutuyor. Bağıntı bu kursun bulgusu değil;
arka plan işleri konusunda kurulmuştu ve burada bir çevirici olarak kullanılıyor.

**Suç sütunları arıza kipini gizliyor.** Açgözlü dağıtımda tarife otuz altı kez başarısız, ölçü
**kırk iki** kez. Ölçünün rejimi hiç değişmedi; kırk iki başarısızlığın tamamı, tarifenin bütçeyi
yemesinden geliyor. Ağırlıklı dağıtımda ölçü sıfır kez başarısız. Aradaki fark bir kayıt farkı
değil, bir teşhis farkıdır: açgözlü dağıtım, yavaşlayan adımı sağlam adımın arkasına saklar ve
zaman aşımı kayıtlarında en çok görünen ad, arızanın yaşandığı yerin adı olmaz.

Bu, bütçe üzerinden **bulaşma**dır. Adımlar birbirinden yalıtılmış görünür — ayrı depolar, ayrı
kayıtlar — ama paylaştıkları tek bir kaynak vardır ve o kaynak süredir. Payı sabitlemek, o tek
paylaşılan kaynağı bölmenin adıdır.

#### Terk Edilen İş

Son sütun buraya kadarki tabloyu tersine çeviriyor. Çağıran vazgeçtiğinde tarife deposu durmaz;
başlattığı okumayı bitirir. Bu iş kimsenin beklemediği iştir ve modelde `bosa is` olarak sayılır:
açgözlü dağıtımda 5540, ağırlıklı dağıtımda 11120 milisaniye. Sıkı bölüştürme, terk edilen işi
**iki katına** çıkarıyor — çünkü daha erken vazgeçmek, bağımlılığın önünde daha uzun bir artık
bırakmak demektir.

Üçüncü tablo iki tarafı toplayarak kararı veriyor. İptal sinyali yokken sistemin meşgul tuttuğu
toplam yuva açgözlüde 130,5, eşitte ve ağırlıklıda 136,7. Neredeyse aynı sayı: bölüştürme, yükü
çağırandan bağımlılığa taşımaktan başka bir şey yapmıyor. Sıkı bölüştürmenin kazancı ancak
**iptal sinyali** varken görünür — çağıran vazgeçtiğini bağımlılığa bildirir ve okuma durdurulur.
O zaman terk edilen iş sıfırlanır ve toplam yuva 82,4'e karşı 40,2 olur.

Karar cümlesi budur: **son tarih aktarımı iptal sinyali olmadan tamamlanmış sayılmaz.** Kalan
süreyi çağrıyla geçirmek, çağıranın ne zaman vazgeçeceğini söyler; iptal sinyali, vazgeçtiğini
söyler. Birincisi olmadan bütçe bölüştürülemez, ikincisi olmadan bölüştürme yalnız yer değiştirir.

Son tablo AY10'un duyarlılığıdır. On iki dakikalık tek bir yavaşlama, K01'in aylık 28,2 dakikalık
arıza payının yüzde 42,6'sını harcar. Aynı yavaşlama ayda iki kez olursa ya da bir kez yirmi dört
dakika sürerse pay yüzde 85,1'e çıkar ve ayın kalanına 4,2 dakika kalır. Bütçe bölüştürmesi bu
dakikaları geri getirmez — istekler yine düşüyor — ama düşen isteğin kaç kaynağı meşgul ettiğini
belirler ve arızanın hangi adımda göründüğünü doğrular.

#### Özet

- Kola kalan pay (200 ms eşik eksi 20 ms ağ geçidi payı = 180 ms) ardışık alt çağrılara üç biçimde
  dağıtılır: açgözlü 180/180, eşit 90/90, ağırlıklı 60/120.
- Arızasız günün bedeli iki kalemdir: son tarih alanı dış istek başına 40 bayt (yanıtın yüzde 8,3'ü,
  tepe uçta 20,07 KiB/s) ve sıkı bölüştürmenin kestiği geçerli istekler — 48'de 2, yüzde 4,17, tepe
  okumada saniyede 17,36 istek.
- AY10 altında açgözlü dağıtım altı isteği kurtarır ama uçtan uca ortancayı 200 ms'de tutar;
  ağırlıklı dağıtım hiçbirini kurtarmaz ve ortancayı 93 ms'ye indirir, tutulan yuvayı 82,4'ten
  40,2'ye düşürür.
- Açgözlü dağıtımda sağlam adım (ölçü) kırk iki kez başarısız görünür, ağırlıklı dağıtımda sıfır
  kez; bölüştürme yalnız kaynak değil, arıza kipinin **teşhisini** de belirler.
- Sıkı bölüştürme terk edilen işi 5540'tan 11120 milisaniyeye çıkarır; iptal sinyali yokken toplam
  meşgul yuva 130,5'e karşı 136,7'dir, yani kazanç yoktur. İptal sinyaliyle toplam 82,4'e karşı
  40,2 olur — bölüştürme ancak iptalle birlikte kazanç yazar.
- On iki dakikalık tek bir yavaşlama K01'in aylık 28,2 dakikalık arıza payının yüzde 42,6'sını
  harcar; ayda iki kez olursa yüzde 85,1.

#### Sonraki Adım

Bütçe, tek bir isteğin ne kadar bekleyeceğine karar verdi ve bu kararı zincire dağıttı. Sessiz
kalan bir varsayım vardı: çağıran her istek için çağrıyı **yapabiliyor**. Yavaşlayan bağımlılık
karşısında bütçe isteği keser, kaynağı geri alır, arızayı doğru adımda gösterir — ama bir sonraki
isteğin gelmesini engellemez. İstekler aynı hızla gelmeye devam eder ve her biri aynı bütçeyi aynı
yavaş adıma harcar. Aynı sorunun ikinci yüzü yazma yolundadır: taşıyıcıdan gelen durum olayları
sabit bir hızla akar, izdüşümü besleyen tüketici yavaşlarsa iş bir yerlerde birikir ve bütçe o
birikime dokunmaz. Sonraki ders bu birikimi ele alır ve soruyu tersine çevirir: sistem, artık
yetişemediğini kendisine iş veren tarafa nasıl **bildirir**, o bildirim zincirde nereye kadar
yayılır ve bildirim hiç yapılmazsa iş nerede toplanır.

### Geri Basınç

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/geri-basinc

Aşırı yük sinyalinin servis sınırından geriye yayılması: yayılma derinliğinin sıfırdan sınıra kadar dört ayarda ölçülmesi, kısmi yayılmanın kaybı yalnız bir halka geriye taşıması, sinyal sınıra ulaştığında kabul edilip kaybolan yazmanın hiç kabul edilmeyen yazmaya dönüşmesi ve sınırsız tamponun kaybı bayatlığa çevirmesi.

Bir önceki ders bütçeyi tek bir isteğin süresine kurdu ve o isteğin kaynağını zamanında geri
almayı öğretti. Bütçenin dokunmadığı bir şey var: isteklerin **gelme hızı**. Yavaşlayan bir
bağımlılık karşısında bütçe her isteği ayrı ayrı keser, ama bir sonraki istek yine gelir ve yine
aynı yavaş adıma harcanır. Bütçe bir isteğin ne kadar bekleyeceğini söyler; sisteme iş veren tarafa
hiçbir şey söylemez.

Bu ders o eksik bildirimi ele alır ve yazma yolunda sorar. Taşıyıcıdan gelen durum olayları sabit
bir hızla akar; olay kütüğünü okuyup okuma modelini besleyen tüketici yavaşlarsa iş bir yerlerde
birikir. Önbellekleme, Kuyruklar ve Eşzamansız İşleme kursu bunu **tek bir kuyrukta** kurdu: sınırlı
kuyruk bir gecikme bütçesi kararıdır, taşma politikaları vardır, engelleme yavaşlığı üreticiye
geçirir ve akış dönüşünü yok sayan katman önündeki sınırı boşa çıkarır. O mekanik burada
tekrarlanmaz. Buradaki soru zincirle ilgilidir: sinyal **kaç halka geriye** taşınır, taşınmadığı
yerde iş nerede toplanır ve yayılma nerede durmak zorundadır.

#### Arıza Kipi ve Zincir

Yazma yolu dört parçadır: taşıyıcının bildirim ucu olayı gönderir, **giriş** servisi kabul eder,
**kütük** yazıcısı kalıcılaştırır, **izdüşüm** tüketicisi okuma modelini günceller. Kaynak sistemin
dışındadır — taşıyıcı başka bir kuruluşun sistemidir ve bu sistemin denetiminde değildir.

**AY11 — izdüşüm tüketicisi geri kalıyor.** Durmuyor, yanlış yazmıyor; işleme hızı turda 120
olaydan 60 olaya iniyor. Süre **20 dakika**, sıklık **ayda üç kez**. Gerekçe: tüketici yavaşlaması
genellikle izdüşüm şemasının değişmesinden ya da yeniden oluşturma işiyle çakışmadan doğar ve iş
bitene kadar sürer. Duyarlılığı aşağıda hesaplanmıştır. Bu varsayım K01'in tablosuna eklenmez.

AY11 bir kesinti değildir; takip sorgusu yanıtlanmaya devam eder, yalnız okuduğu izdüşüm geride
kalır. Bu yüzden K01'in aylık 43,2 dakikalık kesinti bütçesine yazılmaz. Kayıp yazma ise başka bir
ölçüye girer ve eşiği bu kursun kurtarma konusunda konur.

Bir tur soyut bir adımdır; modelde bir saniyelik iş penceresine karşılık gelir ve bu çevrim
katsayısı bir varsayımdır. Kaynağın hızı K01'in tepe yazma sayısıdır: turda 97,22 olay. Varış
düz değil salınımlıdır — ortalaması 1,00 olan bir çarpan döngüsü, tepe saat içindeki dalgalanmayı
temsil eder.

#### Yayılma Derinliği

Sinyal, tüketiciden geriye doğru taşınan tek bir bilgidir: "ardılım dolu, sana iş veremem." Her
halka bu bilgiye uyabilir ya da yok sayabilir. Modelde bu bir parametredir — **derinlik**, sinyalin
tüketiciden kaç halka geriye taşındığı. Derinlik 0'da hiçbir halka uymaz, derinlik 3'te sinyal
servis sınırına ulaşır ve taşıyıcının olayı **kabul edilmez**.

```js
// geri/zincir.mjs — yazma yolunun MODELI. Tur soyut bir adimdir; cevrim katsayisi
// varsayimdir (bir tur = bir saniye). Gercek kuyruk, kutuk ya da tuketici kurulmaz.
export const K01 = { tepeYazma: 97.22 };      // K01: tasiyici durum olayi, tepe yazma/s

// Halkalar kaynaktan uca dogru siralidir. `hiz` bir turda islenen olay sayisidir.
export const HALKA = [
  { ad: "giris", kap: 200, hiz: 250 },        // olay kabul ucu
  { ad: "kutuk", kap: 150, hiz: 150 },        // olay kutugu yazicisi
  { ad: "izdusum", kap: 100, hiz: 120 },      // okuma modelini besleyen tuketici
];

// Tepe saat icinde varisin salinimi: ortalamasi 1,00 olan bir carpan dongusu.
export const SALINIM = [0.6, 0.6, 0.6, 2.2];

// Halka i, ardilinin doluluguna uyuyorsa durur; uymuyorsa olayi kaybeder.
// derinlik: sinyalin tuketiciden geriye kac halka tasindigi. 3 = sinira kadar.
const uyar = (i, derinlik) => derinlik >= HALKA.length - 1 - i;

export function kosum({ turSayisi, derinlik, tuketimHizi, salinim = true, sinirsiz = false }) {
  const hiz = HALKA.map((h, i) => (i === HALKA.length - 1 ? tuketimHizi : h.hiz));
  const kap = HALKA.map((h) => (sinirsiz ? Infinity : h.kap));
  const tampon = HALKA.map(() => []);
  const s = {
    uretilen: 0, tamamlanan: 0, reddedilen: 0, enBuyukYas: 0, sinirDurdu: 0,
    kaybolan: HALKA.map(() => 0), duraklatilan: HALKA.map(() => 0),
  };
  let birikim = 0;

  for (let t = 1; t <= turSayisi; t += 1) {
    for (let i = HALKA.length - 1; i >= 0; i -= 1) {      // uctan kaynaga dogru bosalt
      let n = Math.min(hiz[i], tampon[i].length);
      while (n > 0) {
        if (i === HALKA.length - 1) {                     // son halka: is tamamlanir
          s.enBuyukYas = Math.max(s.enBuyukYas, t - tampon[i].shift());
          s.tamamlanan += 1; n -= 1; continue;
        }
        if (tampon[i + 1].length < kap[i + 1]) { tampon[i + 1].push(tampon[i].shift()); n -= 1; continue; }
        if (uyar(i, derinlik)) { s.duraklatilan[i] += 1; break; }   // ardil dolu: dur
        s.kaybolan[i + 1] += 1; tampon[i].shift(); n -= 1;          // sinyal yok: kaybet
      }
    }
    const carpan = salinim ? SALINIM[(t - 1) % SALINIM.length] : 1;
    birikim += K01.tepeYazma * carpan;
    while (birikim >= 1) {                                // kaynak: tasiyici bildirim ucu
      birikim -= 1; s.uretilen += 1;
      if (tampon[0].length < kap[0]) { tampon[0].push(t); continue; }
      if (derinlik >= HALKA.length) {                     // sinirda reddet: olay kabul edilmez
        s.reddedilen += 1; s.sinirDurdu += 1;
      } else s.kaybolan[0] += 1;                          // kabul edildi, sonra kayboldu
    }
  }
  s.biriken = tampon.reduce((a, b) => a + b.length, 0);
  const bekleyen = tampon.flat();
  s.bekleyenYas = bekleyen.length === 0 ? 0 : turSayisi - Math.min(...bekleyen);
  s.kayipToplam = s.kaybolan.reduce((a, b) => a + b, 0);
  return s;
}
```

İki sayaç ayrı tutulur ve dersin bütün ayrımı buradadır. **Kaybolan** olay, sistemin kabul ettiği
ve sonra düşürdüğü olaydır; taşıyıcı onu gönderilmiş sayar ve bir daha göndermez. **Reddedilen**
olay, sınırda hiç kabul edilmeyendir; taşıyıcı bunu bilir ve kendi politikasıyla yeniden gönderir.

```js
// geri/kosum.mjs — sinyalin geriye yayilma derinligi: iki gunde bes ayar
import { K01, HALKA, kosum } from "./zincir.mjs";

const TUR = 1200;                       // AY11: 20 dakika, bir tur = bir saniye
const ARIZASIZ = 120, YAVAS = 60;       // izdusum tuketicisinin turdaki hizi
const AYAR = [
  ["sinirsiz tampon", { derinlik: 0, sinirsiz: true }],
  ["sinyal yok", { derinlik: 0 }],
  ["1 halka", { derinlik: 1 }],
  ["2 halka", { derinlik: 2 }],
  ["sinira kadar", { derinlik: 3 }],
];

console.log(`${TUR} tur, kaynak K01 tepe yazma ${K01.tepeYazma}/tur (salinimli, ortalama carpan 1.00)`);
console.log(`halkalar: ${HALKA.map((h, i) => `${h.ad}(kap ${h.kap}, hiz ${i === 2 ? "tuketim" : h.hiz})`).join(" -> ")}\n`);

for (const [rejim, hiz] of [["arizasiz: tuketim 120/tur", ARIZASIZ], ["AY11: tuketim 60/tur", YAVAS]]) {
  console.log(`-- ${rejim} --`);
  console.log(`${"ayar".padEnd(16)}${"tamamlanan".padStart(11)}${"reddedilen".padStart(11)}${"kaybolan".padStart(9)}` +
    `${"kayip yeri".padStart(20)}${"biriken".padStart(8)}${"bekleyen yas".padStart(13)}${"biten yas".padStart(10)}`);
  for (const [ad, y] of AYAR) {
    const r = kosum({ turSayisi: TUR, tuketimHizi: hiz, ...y });
    console.log(`${ad.padEnd(16)}${String(r.tamamlanan).padStart(11)}${String(r.reddedilen).padStart(11)}` +
      `${String(r.kayipToplam).padStart(9)}${r.kaybolan.join("/").padStart(20)}${String(r.biriken).padStart(8)}` +
      `${String(r.bekleyenYas).padStart(13)}${String(r.enBuyukYas).padStart(10)}`);
  }
  console.log();
}

const sinirsiz = kosum({ turSayisi: TUR, derinlik: 0, sinirsiz: true, tuketimHizi: ARIZASIZ });
const sinyalli = kosum({ turSayisi: TUR, derinlik: 3, tuketimHizi: ARIZASIZ });
const duz = kosum({ turSayisi: TUR, derinlik: 3, tuketimHizi: ARIZASIZ, salinim: false });
console.log(`-- arizasiz gunun bedeli (sinirsiz tampona gore) --`);
console.log(`uretilen ${sinyalli.uretilen}, sinirda reddedilen gecerli olay ${sinyalli.reddedilen}` +
  ` = %${((sinyalli.reddedilen / sinyalli.uretilen) * 100).toFixed(2)}`);
console.log(`salinim kapatilinca ayni ayar: ${duz.reddedilen} red -> reddin kaynagi ortalama yuk degil, salinimdir`);
console.log(`sinirsiz tamponun bekleyen yasi ${sinirsiz.bekleyenYas} tur, sinira kadar sinyalde ${sinyalli.bekleyenYas} tur`);
console.log(`duraklatilan halka-turu: ${sinyalli.duraklatilan.join("/")}; kaynagin durduruldugu olay ${sinyalli.sinirDurdu}`);
console.log(`sinyal denetimi: ${HALKA.length} halka x ${K01.tepeYazma} olay/s = ${(HALKA.length * K01.tepeYazma).toFixed(2)} denetim/s`);

console.log(`\n-- AY11'in duyarliligi: tuketici hizi (1200 tur) --`);
console.log(`${"tuketim/tur".padStart(12)}${"acik/tur".padStart(10)}${"sinirsiz biriken".padStart(17)}` +
  `${"sinyalsiz kayip".padStart(16)}${"sinirda red".padStart(12)}${"kayip/red".padStart(10)}`);
for (const h of [90, 60, 30]) {
  const a = kosum({ turSayisi: TUR, derinlik: 0, sinirsiz: true, tuketimHizi: h });
  const y = kosum({ turSayisi: TUR, derinlik: 0, tuketimHizi: h });
  const t = kosum({ turSayisi: TUR, derinlik: 3, tuketimHizi: h });
  console.log(`${String(h).padStart(12)}${(K01.tepeYazma - h).toFixed(2).padStart(10)}${String(a.biriken).padStart(17)}` +
    `${String(y.kayipToplam).padStart(16)}${String(t.reddedilen).padStart(12)}` +
    `${(y.kayipToplam / t.reddedilen).toFixed(3).padStart(10)}`);
}
```

```
1200 tur, kaynak K01 tepe yazma 97.22/tur (salinimli, ortalama carpan 1.00)
halkalar: giris(kap 200, hiz 250) -> kutuk(kap 150, hiz 150) -> izdusum(kap 100, hiz tuketim)

-- arizasiz: tuketim 120/tur --
ayar             tamamlanan reddedilen kaybolan          kayip yeri biriken bekleyen yas biten yas
sinirsiz tampon      116301          0        0               0/0/0     362            3         4
sinyal yok            82282          0    34064    4164/14950/14950     317            2         3
1 halka               97224          0    19114        4164/14950/0     325            3         4
2 halka              112124          0     4164            4164/0/0     375            3         4
sinira kadar         112124       4164        0               0/0/0     375            3         4

-- AY11: tuketim 60/tur --
ayar             tamamlanan reddedilen kaybolan          kayip yeri biriken bekleyen yas biten yas
sinirsiz tampon       71814          0        0               0/0/0   44849          460       460
sinyal yok            71814          0    44494    4164/14950/25380     355            3         4
1 halka               71814          0    44404        4164/40240/0     445            5         6
2 halka               71814          0    44399           44399/0/0     450            7         8
sinira kadar          71814      44399        0               0/0/0     450            7         8

-- arizasiz gunun bedeli (sinirsiz tampona gore) --
uretilen 116663, sinirda reddedilen gecerli olay 4164 = %3.57
salinim kapatilinca ayni ayar: 0 red -> reddin kaynagi ortalama yuk degil, salinimdir
sinirsiz tamponun bekleyen yasi 3 tur, sinira kadar sinyalde 3 tur
duraklatilan halka-turu: 598/897/0; kaynagin durduruldugu olay 4164
sinyal denetimi: 3 halka x 97.22 olay/s = 291.66 denetim/s

-- AY11'in duyarliligi: tuketici hizi (1200 tur) --
 tuketim/tur  acik/tur sinirsiz biriken sinyalsiz kayip sinirda red kayip/red
          90      7.22             9029           34064        8579     3.971
          60     37.22            44849           44494       44399     1.002
          30     67.22            80753           80394       80303     1.001
```

Bütün sayılar **hesap** sınıfındadır: belirlenimli bir varış dizisi üzerinde sayılmışlardır.

#### Kısmi Yayılma Kaybı Taşır, Kaldırmaz

İkinci tablo dersin ana bulgusudur. AY11 altında kaybolan olay sayısı derinlik 0'da 44.494, derinlik
1'de 44.404, derinlik 2'de 44.399. Üç sayı birbirinin aynı. Değişen tek şey `kayip yeri`
sütunudur: kayıp önce izdüşümün kapısında (25.380), sonra kütüğün kapısında (40.240), sonra girişin
kapısında (44.399) oluyor.

Kısmi geri basınç hiçbir olay kurtarmıyor; yalnız kaybın **yerini** değiştiriyor. Karşılığında iki
şey ödeniyor: biriken iş 355'ten 450'ye çıkıyor ve bekleyen olayın yaşı 3 turdan 7 tura yükseliyor.
Yani sinyal, işi geriye tutar — tutmak da bir bedeldir.

Dördüncü satırda sayı sıfırlanıyor: sinyal servis sınırına ulaştığında 44.399 olay **kaybolmuyor**,
**reddediliyor**. Tamamlanan olay sayısı değişmedi (71.814); tüketicinin kapasitesi neyse o. Değişen,
o kapasiteye sığmayan 44.399 olayın ne olduğudur. Kaybolan olay taşıyıcı için gönderilmiş sayılır ve
bir daha gelmez; reddedilen olay taşıyıcı için gönderilmemiştir ve yeniden gönderilebilir.

**Geri basınç, servis sınırına ulaşmadıkça hiçbir olayı kurtarmaz.** Zincirin tamamında
uygulanmadıkça hiçbir yerinde uygulanmış sayılmayacağı arka plan işleri konusunda söylenmişti; bu
tablo o cümlenin sayısıdır ve sınırın hangi halka olduğunu ekler — sinyalin durabileceği tek yer,
sistemin dışıyla konuştuğu yerdir.

#### Yayılma Nerede Durmak Zorunda

Sinyal taşıyıcıya taşınamaz. Taşıyıcı başka bir kuruluşun sistemidir; bu sistem onu yavaşlatamaz,
yalnız olayını kabul etmeyebilir. Yayılma bu yüzden zincirin dördüncü halkasında değil, üçüncüsünün
dış kapısında biter ve orada biçim değiştirir: **iç halkalarda bir bekletmedir, sınırda bir
reddir.**

Birinci tablo bunun ilk bedelini gösteriyor. Arızasız günde — tüketici üreticiden hızlıyken —
sınıra kadar taşınan sinyal 4164 geçerli olayı reddediyor: üretilenin yüzde 3,57'si. Salınım
kapatıldığında aynı ayar hiçbir olayı reddetmiyor. Demek ki reddin kaynağı ortalama yük değil,
varışın anlık dalgalanmasıdır. Tampon dalgalanmayı yutmaya yetmediğinde geri basınç, yutulabilecek
bir tepeyi redde çeviriyor.

Aynı satırda ikinci bir bedel var: duraklatılan halka-turu 598 ve 897. Bunlar bir halkanın işi
olduğu hâlde ardılı dolu diye durduğu turlardır — kullanılmayan kapasite.

Sınırsız tampon satırı bu bedeli ödemez: arızasız günde 116.301 olay tamamlar, hiçbirini reddetmez.
Bedeli AY11 satırında görünür. Orada da hiçbir olay kaybolmaz, ama 44.849 olay birikir ve en eski
bekleyen olay **460 tur** yaşındadır — yaklaşık yedi buçuk dakika. İzdüşüm o kadar geridedir ve
takip sorgusu o kadar eski bir durumu gösterir. Sınırsız tampon kaybı yok etmez; onu **bayatlığa**
çevirir.

Üç seçenek üç yere yazar: belleğe ve bayatlığa (sınırsız tampon), kayba (sinyalsiz sınırlı tampon),
ya da kaynağa (sınıra kadar sinyal). Hangisinin seçileceği veriye bağlıdır — bir gönderinin durum
olayı kaybolduğunda takip zinciri kalıcı olarak eksilir, bu yüzden ikinci seçenek bu akış için
kabul edilebilir değildir.

#### Açık Büyüdükçe Kazanç Küçülür

Son tablo AY11'in duyarlılığıdır ve geri basıncın sınırını çizer. Tüketici hızı 90 olduğunda açık
turda yalnız 7,22 olaydır; sinyalsiz düzen 34.064 olay kaybederken sınıra kadar sinyal yalnız 8579
olay reddeder — oran 3,971. Geri basınç burada işin dörtte üçünü **kurtarıyor**, çünkü tepeler
arasındaki boşluklarda biriken iş eritiliyor.

Tüketici hızı 60'a inince oran 1,002'ye, 30'a inince 1,001'e düşüyor. Açık büyüdüğünde geri basınç
hiçbir işi kurtarmıyor, yalnız kaybı redde çeviriyor. Bu yine değerlidir — reddedilen olay yeniden
gönderilebilir — ama iki farklı kazanç olduğunun ve hangisinin geçerli olduğunun açık yazılması
gerekir. Küçük açıklarda geri basınç bir **soğurma** mekanizması, büyük açıklarda bir **etiketleme**
mekanizmasıdır.

#### Özet

- Geri basınç sinyali bir yayılma derinliği taşır: tüketiciden geriye kaç halkanın ardılının
  doluluğuna uyduğu. Derinlik 3, sinyalin servis sınırına ulaşması demektir.
- Kısmi yayılma hiçbir olay kurtarmaz: AY11 altında kaybolan olay derinlik 0, 1 ve 2'de sırasıyla
  44.494, 44.404 ve 44.399 — aynı sayı. Değişen yalnız kaybın yeri, biriken iş (355 → 450) ve
  bekleyen olayın yaşıdır (3 → 7 tur).
- Sinyal sınıra ulaştığında 44.399 olay kaybolmaktan çıkıp reddedilmeye döner; kaybolan olay
  taşıyıcı için gönderilmiştir, reddedilen olay gönderilmemiştir ve yeniden gönderilebilir.
- Arızasız günün bedeli, salınımın yuttuğu tepelerdir: 4164 geçerli olay reddedilir (üretilenin
  yüzde 3,57'si) ve salınım kapatıldığında bu sayı sıfırlanır; ayrıca 598 ile 897 duraklatılmış
  halka-turu ve saniyede 291,66 sinyal denetimi.
- Sınırsız tampon kaybı yok etmez, bayatlığa çevirir: AY11'de 44.849 olay birikir ve en eski bekleyen
  olay 460 tur yaşındadır.
- Kazancın büyüklüğü açığa bağlıdır: turda 7,22 olaylık açıkta geri basınç kaybı 34.064'ten 8579'a
  indirir (oran 3,971), 37,22 olaylık açıkta oran 1,002'dir — orada kurtarma değil etiketleme yapar.

#### Sonraki Adım

Sinyal sınıra ulaştı ve orada bir redde dönüştü. Redde dönüşmesi kaçınılmazdı, ama reddin
**kendisi** bu derste tasarlanmadı: 4164 geçerli olay reddedildiğinde hangileri olduğu, neye göre
seçildiği ve karşı tarafa ne söylendiği hep aynı kaba kurala bağlıydı — tampon doluysa reddet.
Okuma tarafında aynı soru daha keskindir. Uçta saniyede 513,89 istek var ve üçü aynı kapıdan
geçiyor: takip sorgusu, taşıyıcı durum olayı, gün sonu ücretlendirme. Kapasite yetmediğinde hepsi
birden mi kısılacak, yoksa biri korunup ötekiler mi kesilecek. Üstelik iki ayrı soru burada
birbirine karışıyor — bilinen bir hızın üstünü kesmekle o anki kapasiteye göre reddetmek aynı şey
değildir. Sonraki ders ikisini ayırır ve K01'in 513,89 istek/s tepesinde hangi isteğin korunduğunu
sayar.

### Kısıtlama ve Yük Boşaltma

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/kisitlama-ve-yuk-bosaltma

Denetimli hizmet reddinin iki ayrı kararı: kısıtlamanın bilinen bir hızın üstünü kaynakta kesmesi, yük boşaltmanın anlık kapasiteye göre sınıf sırasıyla reddetmesi, kısıtlamanın kapasite kaybını göremeyip yük boşaltmanın boş kapasiteyi kullandırması ve iki mekanizmanın birlikte K01'in 513,89 istek/s tepesinin ne kadarını koruduğunun sayılması.

Bir önceki ders geri basınç sinyalini servis sınırına kadar taşıdı ve orada bir redde dönüştüğünü
gösterdi. Reddin **kendisi** tasarlanmadı: tampon doluysa reddet kuralı, hangi isteğin gideceğini
seçmiyordu. Uçta saniyede 513,89 istek var ve üç akış aynı kapıdan geçiyor — takip sorgusu,
taşıyıcı durum olayı, gün sonu ücretlendirme isteği. Kapasite yetmediğinde hepsi eşit mi kısılacak.

Soruda birbirine karışan iki karar var; bu ders onları ayırır.

#### İki Ayrı Ölçüt

**Kısıtlama** (throttling), bilinen bir hızın üstünü kesmektir. Ölçütü akışın kendisidir: her akış
için olağan hızından türetilmiş bir tavan konur ve tavanı aşan istek reddedilir. Karar sistemin o
anki durumuna bakmaz — kapasite bomboş olsa da tavanı aşan istek geçmez.

**Yük boşaltma** (load shedding), anlık kapasiteye göre reddetmektir. Ölçütü sistemin o anki
doluluğudur: kapasite yeterken hiçbir istek reddedilmez, doygunluğa yaklaşıldığında bir sınıf
sırasına göre reddedilir. Aynı istek, sistem boşken kabul edilir, doluyken reddedilir.

Kabul denetimi, eşiğin eşzamanlılığa konması ve yük boşaltmanın çöküşü önlemesi Önbellekleme,
Kuyruklar ve Eşzamansız İşleme kursunda kuruldu; eşik hesabı burada tekrarlanmaz. Buradaki soru
ikisinin **birlikte** ne yaptığıdır.

İki adlandırma karışıklığı baştan ayrılmalıdır. Trafik Katmanı kursundaki **ağ geçidi yük
boşaltma** (gateway offloading) bu kavramla aynı sözcüğü taşır ama ayrı bir şeydir: o, kimlik
doğrulama ya da TLS sonlandırma gibi bir işi uygulamadan alıp ağ geçidine taşır — iş yine yapılır,
yeri değişir. Buradaki yük boşaltma ise isteği **hiç kabul etmez**. Benzer biçimde, Frontend
Kalitesi kursunda geçen `kısıtlama` sözcüğü bir bağlantının bant genişliğinin sınırlanmasını
anlatır; buradaki kısıtlama aynı fikrin istek hızına uygulanmış hâlidir.

#### Kapı

Model, uç katmandaki tek bir kabul kapısıdır; üç akış aynı kapasiteyi paylaşır ve iş **birim**
cinsinden sayılır.

**AY12 — kapasite ve birim maliyetleri.** Uç katman turda 700 birim işler. Bir takip sorgusu ve bir
durum olayı birer birim, bir gün sonu ücretlendirme isteği 60 birimdir. Gerekçe: toplu istek seyrek
gelir ama K01'de 833,33 kayıt/s'lik bir okuma yürütür; tek bir isteğin maliyeti bu yüzden bir okuma
sorgusundan iki mertebe büyüktür. Olağan talep bu değerlerle turda 603,89 birim, yani kapasitenin
yüzde 86,3'ü.

**AY13 — iki arıza senaryosu.** **AY13a:** gün sonu ücretlendirme işi tepe saate taşıyor; istek hızı
turda 1,5'ten 4,5'e çıkıyor, süre 30 dakika, sıklık ayda iki kez. Gerekçe: dört saatlik pencere
K01'de sabittir, iş uzarsa ya da geç başlarsa tepe saate girer. **AY13b:** bir uç düğümü düşüyor;
kapasite dörtte bir azalıyor (700 → 525), süre 8 dakika, sıklık ayda iki kez. Gerekçe: düğüm kaybı
ile yerine yenisinin gelmesi K01'in on dakikalık kurtarma süresi varsayımının altında kalır.
Duyarlılıkları aşağıda hesaplanmıştır. Bu varsayımlar K01'in tablosuna eklenmez.

Sınıf sırası akışların ne kaybettirdiğinden çıkar: durum olayının kaybı takip zincirini kalıcı
olarak eksiltir (sınıf 1), takip sorgusunun reddi kullanıcıyı bekletir ama yeniden denenebilir
(sınıf 2), gün sonu işi ertelenebilir (sınıf 3). Boşaltma en düşük sınıftan başlar.

```js
// kapi/uc.mjs — uc katmanindaki kabul kapisinin MODELI. Tur soyut bir adimdir
// (bir tur = bir saniye; cevrim katsayisi varsayim). Gercek dugum ya da sunucu kurulmaz.
export const K01 = { takip: 416.67, olay: 97.22, tepeUc: 513.89 };

// AY12: birim maliyetleri ve uc kapasitesi. Bir birim = bir takip sorgusunun isi.
export const AKIS = [
  { ad: "olay", birim: 1, hiz: K01.olay, sinif: 1 },     // tasiyici durum yazmasi
  { ad: "takip", birim: 1, hiz: K01.takip, sinif: 2 },   // kullaniciya donen okuma
  { ad: "toplu", birim: 60, hiz: 1.5, sinif: 3 },        // gun sonu ucretlendirme istegi
];
export const KAPASITE = 700;                  // AY12: turda islenen birim
export const TAVAN_PAYI = 1.2;                // kisitlama tavani = olagan hiz x 1,2
export const SALINIM = [0.85, 0.85, 0.85, 1.45];   // takip akisinin varis salinimi

export function kosum({ turSayisi, kisitlama, bosaltma, kapasite = KAPASITE,
                        topluHizi = 1.5, salinim = true }) {
  const hizlar = AKIS.map((a) => (a.ad === "toplu" ? topluHizi : a.hiz));
  const tavan = AKIS.map((a) => a.hiz * TAVAN_PAYI);   // bilinen olagan hizdan turetilir
  const birikimi = AKIS.map(() => 0);
  const kuyruk = [];                                   // { i, birim, tur }
  const s = {
    gelen: AKIS.map(() => 0), kabul: AKIS.map(() => 0),
    redKisit: AKIS.map(() => 0), redBosalt: AKIS.map(() => 0),
    enBuyukYas: 0,
  };
  const SINIR = 2 * kapasite;                          // bir turluk is bekleyebilir

  for (let t = 1; t <= turSayisi; t += 1) {
    const gelenler = [];
    const kalanTavan = [...tavan];                     // tavan turdan tura tasinmaz
    AKIS.forEach((a, i) => {                           // varis: kesirli hiz birikimle
      const carpan = a.ad === "takip" && salinim ? SALINIM[(t - 1) % SALINIM.length] : 1;
      birikimi[i] += hizlar[i] * carpan;
      while (birikimi[i] >= 1) {
        birikimi[i] -= 1; s.gelen[i] += 1;
        if (kisitlama && kalanTavan[i] < 1) { s.redKisit[i] += 1; continue; }
        kalanTavan[i] -= 1; gelenler.push(i);
      }
    });

    let bekleyen = kuyruk.reduce((x, o) => x + o.birim, 0);
    gelenler.sort((x, y) => AKIS[x].sinif - AKIS[y].sinif);   // once ust sinif kabul edilir
    for (const i of gelenler) {
      if (bosaltma && bekleyen + AKIS[i].birim > SINIR) { s.redBosalt[i] += 1; continue; }
      kuyruk.push({ i, birim: AKIS[i].birim, tur: t });
      bekleyen += AKIS[i].birim; s.kabul[i] += 1;
    }

    let butce = kapasite;                              // turun isleme kapasitesi
    while (kuyruk.length > 0 && kuyruk[0].birim <= butce) {
      const o = kuyruk.shift();
      butce -= o.birim;
      s.enBuyukYas = Math.max(s.enBuyukYas, t - o.tur);
    }
  }
  s.biriken = kuyruk.reduce((x, o) => x + o.birim, 0);
  s.bekleyenYas = kuyruk.length === 0 ? 0 : turSayisi - kuyruk[0].tur;
  return s;
}
```

```js
// kapi/kosum.mjs — kisitlama ile yuk bosaltmanin uc gunde ayri ayri ve birlikte olculmesi
import { K01, AKIS, KAPASITE, TAVAN_PAYI, kosum } from "./uc.mjs";

const TUR = 600;                       // karsilastirma penceresi; toplamlar sureyle dogrusal
const AYAR = [
  ["hicbiri", { kisitlama: false, bosaltma: false }],
  ["yalniz kisitlama", { kisitlama: true, bosaltma: false }],
  ["yalniz bosaltma", { kisitlama: false, bosaltma: true }],
  ["ikisi birden", { kisitlama: true, bosaltma: true }],
];
const GUN = [
  ["arizasiz", {}],
  ["AY13a: toplu is tepe saatte (1,5 -> 4,5 istek/tur)", { topluHizi: 4.5 }],
  ["AY13b: bir uc dugumu dustu (kapasite 700 -> 525)", { kapasite: 525 }],
];

const olagan = AKIS.reduce((x, a) => x + a.hiz * a.birim, 0);
console.log(`kapasite ${KAPASITE} birim/tur; olagan talep ${olagan.toFixed(2)} birim/tur` +
  ` (doluluk %${((olagan / KAPASITE) * 100).toFixed(1)})`);
console.log(`akislar: ${AKIS.map((a) => `${a.ad}(sinif ${a.sinif}, ${a.birim} birim, ${a.hiz}/tur)`).join(", ")}`);
console.log(`kisitlama tavanlari (olagan hiz x ${TAVAN_PAYI}): ` +
  AKIS.map((a) => `${a.ad} ${(a.hiz * TAVAN_PAYI).toFixed(2)}`).join(", "));

for (const [gun, ek] of GUN) {
  console.log(`\n-- ${gun} --`);
  console.log(`${"ayar".padEnd(18)}${"karsilanan olay/takip/toplu".padStart(28)}` +
    `${"kisit reddi".padStart(15)}${"bosaltma reddi".padStart(16)}${"en buyuk yas".padStart(13)}` +
    `${"biriken".padStart(8)}${"bekleyen yas".padStart(13)}`);
  for (const [ad, y] of AYAR) {
    const r = kosum({ turSayisi: TUR, ...y, ...ek });
    console.log(`${ad.padEnd(18)}${r.kabul.join("/").padStart(28)}` +
      `${r.redKisit.join("/").padStart(15)}${r.redBosalt.join("/").padStart(16)}` +
      `${String(r.enBuyukYas).padStart(13)}${String(r.biriken).padStart(8)}` +
      `${String(r.bekleyenYas).padStart(13)}`);
  }
}

console.log(`\n-- AY13b'de korunan tepe --`);
const dus = kosum({ turSayisi: TUR, kisitlama: false, bosaltma: true, kapasite: 525 });
const korunan = (dus.kabul[0] + dus.kabul[1]) / TUR;
console.log(`bosaltma acikken karsilanan olay+takip = ${korunan.toFixed(2)} istek/tur;` +
  ` K01 tepe uc ${K01.tepeUc} istek/s -> orani ${(korunan / K01.tepeUc).toFixed(4)}`);
console.log(`toplu akisin birim yuku ${(AKIS[2].hiz * AKIS[2].birim).toFixed(2)}/tur, dugum kaybinin acigi` +
  ` ${(AKIS.reduce((x, a) => x + a.hiz * a.birim, 0) - 525).toFixed(2)}/tur`);
const [DK, KEZ, ARIZA_PAYI] = [8, 2, 28.2];      // AY13b suresi ve K01 aylik ariza payi (dk)
console.log(`kapisiz duzende AY13b bir kesintidir: ${DK} dk x ${KEZ} = ${DK * KEZ} dk/ay =` +
  ` K01 ariza payinin (${ARIZA_PAYI} dk) %${(((DK * KEZ) / ARIZA_PAYI) * 100).toFixed(1)}'i`);
console.log(`kapili duzende ayni sure kesinti degil kismi reddir:` +
  ` ${(dus.redBosalt.reduce((x, y) => x + y, 0) / TUR).toFixed(2)} istek/tur reddedilir`);

console.log(`\n-- arizasiz gunun bedeli --`);
const k = kosum({ turSayisi: TUR, kisitlama: true, bosaltma: false });
const kd = kosum({ turSayisi: TUR, kisitlama: true, bosaltma: false, salinim: false });
const b = kosum({ turSayisi: TUR, kisitlama: false, bosaltma: true });
const h = kosum({ turSayisi: TUR, kisitlama: false, bosaltma: false });
console.log(`kisitlama: ${k.redKisit[1]} gecerli takip sorgusu reddedildi = gelenin` +
  ` %${((k.redKisit[1] / k.gelen[1]) * 100).toFixed(2)}, tepe okumada ${((K01.takip * k.redKisit[1]) / k.gelen[1]).toFixed(2)} istek/s`);
console.log(`salinim kapatilinca ayni ayar: ${kd.redKisit[1]} red -> tavani asan sey ortalama hiz degil, tepedir`);
console.log(`bosaltma: ${b.redBosalt.reduce((x, y) => x + y, 0)} red, en buyuk yas ${b.enBuyukYas} tur` +
  ` (kapisiz duzende ${h.enBuyukYas} tur)`);
console.log(`her istek iki denetimden gecer: akis tavani ve doluluk -> istek basina 2 denetim`);

console.log(`\n-- AY13'un duyarliligi --`);
console.log(`${"senaryo".padEnd(26)}${"ikisi birden: olay/takip/toplu".padStart(31)}${"toplam red".padStart(11)}`);
for (const [ad, ek] of [["toplu 3,0 istek/tur", { topluHizi: 3 }], ["toplu 6,0 istek/tur", { topluHizi: 6 }],
                        ["kapasite 595 (%15 kayip)", { kapasite: 595 }], ["kapasite 455 (%35 kayip)", { kapasite: 455 }]]) {
  const r = kosum({ turSayisi: TUR, kisitlama: true, bosaltma: true, ...ek });
  const red = r.redKisit.reduce((x, y) => x + y, 0) + r.redBosalt.reduce((x, y) => x + y, 0);
  console.log(`${ad.padEnd(26)}${r.kabul.join("/").padStart(31)}${String(red).padStart(11)}`);
}
```

```
kapasite 700 birim/tur; olagan talep 603.89 birim/tur (doluluk %86.3)
akislar: olay(sinif 1, 1 birim, 97.22/tur), takip(sinif 2, 1 birim, 416.67/tur), toplu(sinif 3, 60 birim, 1.5/tur)
kisitlama tavanlari (olagan hiz x 1.2): olay 116.66, takip 500.00, toplu 1.80

-- arizasiz --
ayar               karsilanan olay/takip/toplu    kisit reddi  bosaltma reddi en buyuk yas biriken bekleyen yas
hicbiri                       58331/250002/900          0/0/0           0/0/0            1     122            0
yalniz kisitlama              58331/234372/600    0/15630/300           0/0/0            0       0            0
yalniz bosaltma               58331/250002/900          0/0/0           0/0/0            1     122            0
ikisi birden                  58331/234372/600    0/15630/300           0/0/0            0       0            0

-- AY13a: toplu is tepe saatte (1,5 -> 4,5 istek/tur) --
ayar               karsilanan olay/takip/toplu    kisit reddi  bosaltma reddi en buyuk yas biriken bekleyen yas
hicbiri                      58331/250002/2700          0/0/0           0/0/0           67   52266           66
yalniz kisitlama              58331/234372/600   0/15630/2100           0/0/0            0       0            0
yalniz bosaltma              58331/250002/1872          0/0/0         0/0/828            1     680            0
ikisi birden                  58331/234372/600   0/15630/2100           0/0/0            0       0            0

-- AY13b: bir uc dugumu dustu (kapasite 700 -> 525) --
ayar               karsilanan olay/takip/toplu    kisit reddi  bosaltma reddi en buyuk yas biriken bekleyen yas
hicbiri                       58331/250002/900          0/0/0           0/0/0           81   48983           80
yalniz kisitlama              58331/234372/600    0/15630/300           0/0/0           29   15624           28
yalniz bosaltma               58331/229912/454          0/0/0     0/20090/446            1     525            0
ikisi birden                  58331/229852/455    0/15630/300      0/4520/145            1     525            0

-- AY13b'de korunan tepe --
bosaltma acikken karsilanan olay+takip = 480.40 istek/tur; K01 tepe uc 513.89 istek/s -> orani 0.9348
toplu akisin birim yuku 90.00/tur, dugum kaybinin acigi 78.89/tur
kapisiz duzende AY13b bir kesintidir: 8 dk x 2 = 16 dk/ay = K01 ariza payinin (28.2 dk) %56.7'i
kapili duzende ayni sure kesinti degil kismi reddir: 34.23 istek/tur reddedilir

-- arizasiz gunun bedeli --
kisitlama: 15630 gecerli takip sorgusu reddedildi = gelenin %6.25, tepe okumada 26.05 istek/s
salinim kapatilinca ayni ayar: 0 red -> tavani asan sey ortalama hiz degil, tepedir
bosaltma: 0 red, en buyuk yas 1 tur (kapisiz duzende 1 tur)
her istek iki denetimden gecer: akis tavani ve doluluk -> istek basina 2 denetim

-- AY13'un duyarliligi --
senaryo                    ikisi birden: olay/takip/toplu toplam red
toplu 3,0 istek/tur                      58331/234372/600      16830
toplu 6,0 istek/tur                      58331/234372/600      18630
kapasite 595 (%15 kayip)                 58331/234372/600      15930
kapasite 455 (%35 kayip)                   58331/214820/5      36077
```

Bütün sayılar **hesap** sınıfındadır: belirlenimli bir varış dizisi üzerinde sayılmışlardır.

#### Arızasız Günün Bedeli

**Kısıtlama arızasız günde ödetir.** Takip akışının tavanı turda 500,00 istek; varış salınımı
tepede 604,17 isteğe çıkınca aradaki fark reddedilir. Altı yüz turda 15.630 geçerli takip sorgusu
gider — gelenin yüzde 6,25'i, K01'in tepe okuma hızında saniyede 26,05 istek. Salınım kapatıldığında
aynı ayar hiçbir isteği reddetmiyor; demek ki tavanı aşan şey ortalama hız değil, tepedir. Üstelik
kapasite o anda boştu (`en buyuk yas` ve `biriken` sıfır): kısıtlama, kullanılabilir kapasiteyi
kullandırmadan reddeder.

**Yük boşaltma arızasız günde ödetmez.** Doluluk sınırına yaklaşılmadığı için hiçbir istek
reddedilmiyor ve `en buyuk yas` kapısız düzendekiyle aynı: 1 tur. Bedeli redde değil, **geç tepki
vermesinde**dir.

Ortak bedel küçüktür: her istek iki denetimden geçer, akış tavanı ve doluluk.

#### İki Arıza, İki Mekanizma

İkinci ve üçüncü tablolar iki mekanizmanın **farklı arıza kiplerini** yakaladığını gösteriyor.

**AY13a'da (toplu iş tepe saate taşıyor) kısıtlama üstün.** Kapısız düzende gecikme 67 tura,
biriken iş 52.266 birime çıkıyor — bu bir çöküştür. Kısıtlama toplu akışın tavanını turda 1,80'de
tuttuğu için 2100 fazla isteği daha kapıda keser; gecikme sıfır, biriken sıfır. Boşaltma da çöküşü
önlüyor ama farklı davranıyor: boş kapasiteyi kullandırdığı için 1872 toplu isteği kabul ediyor,
kısıtlamanın kabul ettiğinin **3,1 katı**; karşılığı bir turluk gecikme ve 680 birimlik birikimdir.

**AY13b'de (bir uç düğümü düşüyor) kısıtlama işe yaramıyor.** Hiçbir akış tavanını aşmıyor —
akışlar olağan hızlarında. Kısıtlama hiçbir şey reddetmiyor ve kapasite 525'e indiği için gecikme
29 tura, biriken iş 15.624 birime çıkıyor. Boşaltma aynı senaryoda gecikmeyi 1 turda, birikeni 525
birimde tutuyor.

Ayrımın kaynağı ölçüttür: kısıtlamanın tavanı **bilinen bir hızdan** türetilir ve kapasite
değiştiğinde değişmez, bu yüzden kapasite kaybı hiçbir tavanı ihlal etmez ve kısıtlama onu göremez.

Son satır ikisini birlikte çalıştırıyor ve her iki senaryoda da en iyi sonucu veriyor: hiçbiri
ötekini gereksizleştirmiyor.

#### Korunan Tepe

Asıl soru hangi isteğin korunduğuydu. AY13b'de boşaltma açıkken karşılanan durum olayı ile takip
sorgusu toplamı turda 480,40 istek — K01'in 513,89 istek/s tepesinin **0,9348'i**. Durum olayı
akışının tamamı korunuyor (58.331 istek); kesilen 20.090 takip sorgusu ile 446 toplu istektir.

Aritmetiği tabloda: düğüm kaybının açığı turda 78,89 birim, toplu akışın yükü 90,00 birim. Toplu
akışı tümüyle kesmek açığı kapatmaya yeter — ama boşaltma yalnız doygunlukta tepki verdiği için
varış tepelerinde kuyruk sınıra dayanır ve o turlarda takip sorgusundan da kesilir. Sınıf sırası
neyin **önce** kesileceğini belirler, hiçbir şeyin kesilmeyeceğini değil.

Kapı olmasaydı bu on altı dakika bir kesinti olurdu: gecikme 81 tura çıkıyor ve hiçbir istek
zamanında karşılanmıyor. Aylık iki koşumla 16 dakika, K01'in 28,2 dakikalık arıza payının yüzde
56,7'sidir. Kapıyla birlikte aynı süre bir kesinti değil, kısmi bir reddir — bütçeye yazılan
dakika sıfırdır, karşılığında turda 34,23 istek reddedilmiştir.

Son tablo duyarlılıktır. Toplu akışın hızı 3,0 da olsa 6,0 da olsa, kapasite kaybı yüzde 15'te de
kalsa karşılanan istek sayısı değişmiyor: kısıtlama tavanı bağladığı için kaynaktaki anormalliğin
büyüklüğü sonuca geçmiyor. Yüzde 35 kayıpta ise takip 214.820'ye, toplu akış 600'den 5 isteğe
iniyor — sınıf sırası önce en düşük sınıfı tüketiyor, sonra korunan sınıfa giriyor.

#### Özet

- Kısıtlama bilinen bir hızın üstünü kaynakta keser (ölçüt akış), yük boşaltma anlık kapasiteye göre
  sınıf sırasıyla reddeder (ölçüt doluluk); Trafik Katmanı kursundaki ağ geçidi yük boşaltma işi ağ
  geçidine taşır, buradaki ise isteği hiç kabul etmez.
- Arızasız günün bedeli yalnız kısıtlamaya aittir: 15.630 geçerli takip sorgusu reddedilir (gelenin
  yüzde 6,25'i, tepe okumada 26,05 istek/s) ve salınım kapatıldığında bu sayı sıfırlanır. Boşaltma
  arızasız günde hiçbir isteği reddetmez.
- AY13a'da (toplu iş tepe saate taşıyor) kapısız düzen 67 turluk gecikmeyle çöküyor; kısıtlama
  gecikmeyi sıfırlıyor, boşaltma da çöküşü önlüyor ve boş kapasiteyi kullandırdığı için 3,1 kat
  daha çok toplu isteği geçiriyor.
- AY13b'de (bir uç düğümü düşüyor) kısıtlama hiçbir şey reddetmiyor ve gecikme 29 tura çıkıyor;
  ölçütü akış olduğu için kapasite kaybını göremiyor. Boşaltma gecikmeyi 1 turda tutuyor.
- Boşaltma AY13b'de K01'in 513,89 istek/s tepesinin 0,9348'ini koruyor ve durum olayı akışını tümüyle
  ayakta tutuyor; kapısız düzende aynı 16 dakika K01'in 28,2 dakikalık arıza payının yüzde 56,7'sini
  yerdi.

#### Sonraki Adım

Kapı, kabul edilen isteğe verilen sözü tuttu ve kabul edilmeyeni açıkça reddetti. Bir boşluk
kaldı. AY13b'de kesilen 20.090 takip sorgusu tümüyle boşa gitti — oysa takip sorgusunun yanıtı tek
parça değildir: gönderinin durumu, tahmini teslim zamanı ve ücret ayrı alanlardır ve ayrı
bağımlılıklardan gelir. Bir bağımlılık düştüğünde isteğin tamamını düşürmek, elde olan alanları da
atmak demektir. Sonraki ders bunu ele alır: yanıtın hangi parçasının çekirdek olduğuna karar
vermek, çekirdek dışındaki alanlar gelmediğinde isteği yine de yanıtlamak ve bunun arızasız günde
neye mal olduğunu saymak.

### Zarif Bozulma

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/zarif-bozulma

Yanıtın çekirdek kümesinin ayrılması ve eksik alanlarla yanıtlanması: alan atlama ile bayat yedeğin K01'in 480 baytlık takip yanıtı üzerinde ölçülmesi, isteğe bağlı bir bağımlılık düştüğünde 15 dakikalık kesintinin sıfırlanması, çekirdek bağımlılık düştüğünde aynı kalıbın kesintiyi yalnız 14,02 dakikaya indirmesi ve yalıtımın sınırının bu farkla yazılması.

Bir önceki ders kapıyı kurdu ve reddedilen isteği açıkça reddetti. Reddin bir sağlaması eksik
kaldı: bir istek düştüğünde onun için o ana kadar toplanmış her şey de düşüyor. Takip sorgusunun
yanıtı tek parça değildir — gönderinin durumu, rotası, tahmini teslim zamanı ve ücreti ayrı
alanlardır ve ayrı bağımlılıklardan gelir. Bir bağımlılık düştüğünde isteğin tamamını düşürmek,
elde olan üç alanı da atmak demektir.

Bu ders son seçeneği ele alır: yanıtın hangi parçasının çekirdek olduğuna karar vermek ve çekirdek
dışındaki alanlar gelmediğinde isteği yine de yanıtlamak. Adı **zarif bozulma**dır (graceful
degradation) ve **zarif kapanma** (graceful shutdown) ile karıştırılmamalıdır: zarif kapanma, bir
sürecin kapanırken elindeki işi bitirip yeni iş almamasıdır ve Sunucu Tarafı Temelleri ile
Önbellekleme, Kuyruklar ve Eşzamansız İşleme kurslarında kuruldu. Zarif bozulma ise ayakta kalan
bir sistemin **yanıtının içeriğini** küçültmesidir.

#### Alanlar ve Çekirdek Küme

**AY14 — çekirdek küme, yedek defteri ve iki arıza senaryosu.** Çekirdek küme `durum` ve `rota`
alanlarıdır; `tahmin` ile `ucret` isteğe bağlıdır. Gerekçe: takip sayfası gönderinin nerede ve
hangi durumda olduğunu göstermeden anlamsızdır, tahmini teslim ile ücret ise o sayfanın yardımcı
bilgileridir. Yedek defteri son bilinen değeri 5000 gönderi için tutar ve bayat bir değer en çok 60
tur sunulur. **AY14a:** ücretlendirme servisi duruyor, süre 15 dakika, sıklık ayda bir kez.
**AY14b:** izdüşüm okuma modeli duruyor, süre 15 dakika, sıklık ayda bir kez. İki senaryonun süresi
K01'in on dakikalık kurtarma süresi varsayımının biraz üstündedir. Bu varsayımlar K01'in tablosuna
eklenmez.

Alanların bayt boyları K01'in 480 baytlık takip yanıtını bölüştürür: durum 180, rota 120, tahmin
90, ücret 90. Üç politika karşılaştırılır. **Hepsi ya da hiçbiri** bir alan eksikse isteği düşürür.
**Alan atlama** çekirdeği zorunlu tutar, eksik isteğe bağlı alanı yanıttan çıkarır. **Bayat yedek**
buna ek olarak son bilinen değeri sunar — bayat sunum da bir bozulma biçimidir ve bayatlık sınırı
onun genişliğini belirler.

```js
// bozulma/yanit.mjs — takip yanitinin MODELI: alanlar ayri bagimliliklardan toplanir.
// Tur soyut bir adimdir (bir tur = bir saniye) ve her tur akistan bir ornek istegi
// temsil eder. Gercek servis, ag ya da depo kurulmaz.
export const K01 = { tepeOkuma: 416.67, yanitBayt: 480, arizaPayi: 28.2 };

// AY14: cekirdek kume {durum, rota}; toplam bayt K01'in 480 baytlik takip yanitini verir.
export const ALAN = [
  { ad: "durum", kaynak: "izdusum", cekirdek: true, bayt: 180 },
  { ad: "rota", kaynak: "izdusum", cekirdek: true, bayt: 120 },
  { ad: "tahmin", kaynak: "tahmin", cekirdek: false, bayt: 90 },
  { ad: "ucret", kaynak: "ucretlendirme", cekirdek: false, bayt: 90 },
];
export const ISARET_BAYT = 6;            // alan basina tazelik gostergesi
export const YEDEK_KAYIT = 5000;         // yedek defterinde tutulan gonderi sayisi
export const BAYATLIK_SINIRI = 60;       // AY14: bayat deger en cok 60 tur sunulur
const GECICI = 40;                       // saglam bagimlilikta gecici zaman asimi araligi

export function kosum({ politika, kip, isinma = 120, ariza = 900 }) {
  const yedek = new Map();               // alan -> son taze degerin turu
  const s = {
    tam: 0, azaltilmis: 0, dusen: 0, tazeAlan: 0, bayatAlan: 0, eksikAlan: 0,
    yanlisBozulma: 0, toplamBayt: 0, sonYanitTuru: 0,
  };

  for (let t = 1; t <= isinma + ariza; t += 1) {
    const arizada = t > isinma;
    const sonuc = [];
    ALAN.forEach((a, i) => {
      const durum = arizada ? kip[a.kaynak] : "saglam";
      const gecici = durum === "saglam" && (t + i * 10) % GECICI === 0;
      if (durum === "saglam" && gecici === false) {
        yedek.set(a.ad, t); sonuc.push({ a, hal: "taze" }); return;
      }
      const yas = yedek.has(a.ad) ? t - yedek.get(a.ad) : Infinity;
      if (politika === "yedekli" && yas <= BAYATLIK_SINIRI) {
        sonuc.push({ a, hal: "bayat" });
        if (gecici && arizada) s.yanlisBozulma += 1;   // taze deger vardi, gecici asim kesti
        return;
      }
      sonuc.push({ a, hal: "yok" });
    });
    if (arizada === false) continue;      // isinma turlari sayilmaz

    const eksikCekirdek = sonuc.some((o) => o.a.cekirdek && o.hal === "yok");
    const eksikVar = sonuc.some((o) => o.hal !== "taze");
    if (politika === "hepsi" ? eksikVar : eksikCekirdek) { s.dusen += 1; continue; }

    let bayt = 0;
    for (const o of sonuc) {
      if (o.hal === "taze") s.tazeAlan += 1;
      else if (o.hal === "bayat") s.bayatAlan += 1;
      else { s.eksikAlan += 1; continue; }
      bayt += o.a.bayt + ISARET_BAYT;
    }
    s.toplamBayt += bayt;
    s.sonYanitTuru = t - isinma;
    if (eksikVar) s.azaltilmis += 1; else s.tam += 1;
  }
  s.yanit = s.tam + s.azaltilmis;
  s.ortBayt = s.yanit === 0 ? 0 : s.toplamBayt / s.yanit;
  s.tur = ariza;
  return s;
}
```

Isınma turları arızanın sistemin bir süre sağlam çalıştıktan **sonra** başladığını temsil eder.
Yedek defteri ancak o sürede doldurulmuş bir değeri sunabilir; hiç görülmemiş bir alanın yedeği
yoktur.

```js
// bozulma/kosum.mjs — uc politikanin uc gunde karsilastirilmasi ve yalitimin siniri
import { K01, ALAN, ISARET_BAYT, YEDEK_KAYIT, BAYATLIK_SINIRI, kosum } from "./yanit.mjs";

const ARIZA = 900;                 // AY14: 15 dakika = 900 tur
const POLITIKA = [["hepsi ya da hicbiri", "hepsi"], ["alan atlama", "atlama"], ["+ bayat yedek", "yedekli"]];
const SAGLAM = { izdusum: "saglam", tahmin: "saglam", ucretlendirme: "saglam" };
const GUN = [
  ["arizasiz", SAGLAM],
  ["AY14a: ucretlendirme durdu (istege bagli alan)", { ...SAGLAM, ucretlendirme: "dusuk" }],
  ["AY14b: izdusum durdu (cekirdek alan)", { ...SAGLAM, izdusum: "dusuk" }],
];

console.log(`${ARIZA} tur (120 tur isinmadan sonra); bayatlik siniri ${BAYATLIK_SINIRI} tur`);
console.log(`alanlar: ` + ALAN.map((a) => `${a.ad}(${a.kaynak}, ${a.cekirdek ? "cekirdek" : "istege bagli"}, ${a.bayt} B)`).join(", "));
console.log(`toplam alan bayti ${ALAN.reduce((x, a) => x + a.bayt, 0)} = K01 takip yaniti ${K01.yanitBayt} B\n`);

for (const [gun, kip] of GUN) {
  console.log(`-- ${gun} --`);
  console.log(`${"politika".padEnd(20)}${"yanit".padStart(6)}${"tam".padStart(5)}${"azaltilmis".padStart(11)}` +
    `${"dusen".padStart(6)}${"taze/bayat/eksik alan".padStart(22)}${"ort. bayt".padStart(10)}${"son yanit turu".padStart(15)}`);
  for (const [ad, p] of POLITIKA) {
    const r = kosum({ politika: p, kip, ariza: ARIZA });
    console.log(`${ad.padEnd(20)}${String(r.yanit).padStart(6)}${String(r.tam).padStart(5)}` +
      `${String(r.azaltilmis).padStart(11)}${String(r.dusen).padStart(6)}` +
      `${`${r.tazeAlan}/${r.bayatAlan}/${r.eksikAlan}`.padStart(22)}${r.ortBayt.toFixed(1).padStart(10)}` +
      `${String(r.sonYanitTuru).padStart(15)}`);
  }
  console.log();
}

const a = kosum({ politika: "hepsi", kip: SAGLAM, ariza: ARIZA });
const y = kosum({ politika: "yedekli", kip: SAGLAM, ariza: ARIZA });
console.log(`-- arizasiz gunun bedeli --`);
console.log(`tazelik gostergesi ${ISARET_BAYT} B x ${ALAN.length} alan = ${ISARET_BAYT * ALAN.length} B/yanit` +
  ` = K01 yanitinin %${((ISARET_BAYT * ALAN.length) / K01.yanitBayt * 100).toFixed(1)}'i,` +
  ` tepe okumada ${((K01.tepeOkuma * ISARET_BAYT * ALAN.length) / 1024).toFixed(2)} KiB/s`);
console.log(`yedek defteri ${YEDEK_KAYIT} gonderi x ${K01.yanitBayt} B = ` +
  `${((YEDEK_KAYIT * K01.yanitBayt) / 1024 / 1024).toFixed(2)} MiB; her taze alan bir defter yazmasi ->` +
  ` ${(K01.tepeOkuma * ALAN.length).toFixed(2)} yazma/s`);
console.log(`kati politika arizasiz gunde ${a.dusen}/${ARIZA} istegi dusuruyor` +
  ` -> tepe okumada ${((K01.tepeOkuma * a.dusen) / ARIZA).toFixed(2)} istek/s`);
console.log(`bayat yedekle ayni gunde ${y.dusen} dusen, ${y.bayatAlan} alan bayat sunuluyor` +
  ` = alanlarin %${((y.bayatAlan / (ARIZA * ALAN.length)) * 100).toFixed(2)}'i`);

console.log(`\n-- kesinti butcesine yansimasi (AY14: 15 dk, ayda 1 kez) --`);
console.log(`${"senaryo".padEnd(9)}${"politika".padEnd(21)}${"karsilanan".padStart(11)}` +
  `${"kesinti(dk)".padStart(12)}${"ariza payinin(28,2)".padStart(20)}`);
for (const [ad, kip] of [["AY14a", GUN[1][1]], ["AY14b", GUN[2][1]]]) {
  for (const [pad, p] of POLITIKA) {
    const r = kosum({ politika: p, kip, ariza: ARIZA });
    const dk = 15 * (r.dusen / ARIZA);
    console.log(`${ad.padEnd(9)}${pad.padEnd(21)}${String(r.yanit).padStart(11)}` +
      `${dk.toFixed(2).padStart(12)}${`%${((dk / K01.arizaPayi) * 100).toFixed(1)}`.padStart(20)}`);
  }
}

console.log(`\n-- yalitimin siniri: hangi kaynagin dusmesi ne birakiyor --`);
console.log(`${"dusen kaynak".padEnd(16)}${"etkilenen alan".padStart(15)}${"cekirdek mi".padStart(12)}` +
  `${"yanit".padStart(7)}${"ort. bayt".padStart(10)}${"son yanit turu".padStart(15)}`);
for (const kaynak of ["ucretlendirme", "tahmin", "izdusum"]) {
  const et = ALAN.filter((x) => x.kaynak === kaynak);
  const r = kosum({ politika: "yedekli", kip: { ...SAGLAM, [kaynak]: "dusuk" }, ariza: ARIZA });
  console.log(`${kaynak.padEnd(16)}${et.map((x) => x.ad).join("+").padStart(15)}` +
    `${(et.some((x) => x.cekirdek) ? "evet" : "hayir").padStart(12)}` +
    `${String(r.yanit).padStart(7)}${r.ortBayt.toFixed(1).padStart(10)}${String(r.sonYanitTuru).padStart(15)}`);
}
```

```
900 tur (120 tur isinmadan sonra); bayatlik siniri 60 tur
alanlar: durum(izdusum, cekirdek, 180 B), rota(izdusum, cekirdek, 120 B), tahmin(tahmin, istege bagli, 90 B), ucret(ucretlendirme, istege bagli, 90 B)
toplam alan bayti 480 = K01 takip yaniti 480 B

-- arizasiz --
politika             yanit  tam azaltilmis dusen taze/bayat/eksik alan ort. bayt son yanit turu
hepsi ya da hicbiri    810  810          0    90              3240/0/0     504.0            899
alan atlama            856  810         46    44             3378/0/46     498.8            900
+ bayat yedek          900  810         90     0             3510/90/0     504.0            900

-- AY14a: ucretlendirme durdu (istege bagli alan) --
politika             yanit  tam azaltilmis dusen taze/bayat/eksik alan ort. bayt son yanit turu
hepsi ya da hicbiri      0    0          0   900                 0/0/0       0.0              0
alan atlama            856    0        856    44            2545/0/879     405.4            900
+ bayat yedek          900    0        900     0          2633/127/840     414.4            900

-- AY14b: izdusum durdu (cekirdek alan) --
politika             yanit  tam azaltilmis dusen taze/bayat/eksik alan ort. bayt son yanit turu
hepsi ya da hicbiri      0    0          0   900                 0/0/0       0.0              0
alan atlama              0    0          0   900                 0/0/0       0.0              0
+ bayat yedek           59    0         59   841             115/121/0     504.0             59

-- arizasiz gunun bedeli --
tazelik gostergesi 6 B x 4 alan = 24 B/yanit = K01 yanitinin %5.0'i, tepe okumada 9.77 KiB/s
yedek defteri 5000 gonderi x 480 B = 2.29 MiB; her taze alan bir defter yazmasi -> 1666.68 yazma/s
kati politika arizasiz gunde 90/900 istegi dusuruyor -> tepe okumada 41.67 istek/s
bayat yedekle ayni gunde 0 dusen, 90 alan bayat sunuluyor = alanlarin %2.50'i

-- kesinti butcesine yansimasi (AY14: 15 dk, ayda 1 kez) --
senaryo  politika              karsilanan kesinti(dk) ariza payinin(28,2)
AY14a    hepsi ya da hicbiri            0       15.00               %53.2
AY14a    alan atlama                  856        0.73                %2.6
AY14a    + bayat yedek                900        0.00                %0.0
AY14b    hepsi ya da hicbiri            0       15.00               %53.2
AY14b    alan atlama                    0       15.00               %53.2
AY14b    + bayat yedek                 59       14.02               %49.7

-- yalitimin siniri: hangi kaynagin dusmesi ne birakiyor --
dusen kaynak     etkilenen alan cekirdek mi  yanit ort. bayt son yanit turu
ucretlendirme             ucret       hayir    900     414.4            900
tahmin                   tahmin       hayir    900     414.4            900
izdusum              durum+rota        evet     59     504.0             59
```

Bütün sayılar **hesap** sınıfındadır: belirlenimli bir tur dizisi üzerinde sayılmışlardır.

#### Arızasız Günün Bedeli

Üç kalem ödenir ve üçü de arıza olmadan ödenir.

**Taşınan alan.** Her alan yanında bir tazelik göstergesi taşır: değerin taze mi bayat mı olduğu ve
bayatsa yaşı. Altı bayt, dört alan, yanıt başına 24 bayt — K01'in 480 baytlık takip yanıtının yüzde
5,0'i, tepe okuma hızında saniyede 9,77 KiB. Bu gösterge olmadan bozulma sessizdir ve sessiz
bozulma en tehlikeli biçimidir: istemci eski bir ücreti güncel sanır.

**Yedek defteri.** Beş bin gönderinin son bilinen değeri 2,29 MiB tutar, ama asıl bedel bellek değil
yazmadır: her taze alan defteri günceller, tepe okumada saniyede 1666,68 defter yazması. Bu, hiçbir
arıza olmasa da sürekli ödenen bir yüktür ve bozulma kalıbının en pahalı kalemidir.

**Bayat sunulan alan.** Bayat yedek açıkken arızasız günde bile 3600 alanın 90'ı bayat sunuluyor —
yüzde 2,50. Bunlar geçici zaman aşımlarıdır; taze değer bir sonraki turda gelecekti ama yedek
hemen devreye girdi. Yedek yolun kendi tazeliği bir bedeldir.

Buna karşılık ilk tablo katı politikanın kendi bedelini de gösteriyor: arızasız günde 900 isteğin
90'ını düşürüyor, tepe okumada saniyede 41,67 istek. Hiçbir bağımlılık düşmemişken. Katı politika
bir taban değil, kendi başına bir kusurdur.

#### Arızalı Günün Kazancı

AY14a tablosu kalıbın ne satın aldığını gösteriyor. Ücretlendirme servisi on beş dakika durduğunda
katı politika 900 isteğin 900'ünü düşürüyor: on beş dakikanın tamamı kesintidir ve K01'in aylık
28,2 dakikalık arıza payının yüzde 53,2'sini yer. Tek bir arıza, ayın yarısından fazlasını
harcıyor.

Alan atlama aynı arızada 856 isteği yanıtlıyor ve kesinti 0,73 dakikaya iniyor — payın yüzde 2,6'sı.
Bayat yedek eklendiğinde 900 isteğin 900'ü yanıtlanıyor ve **kesinti sıfırlanıyor**. Yanıtın
ortalama boyu 504 bayttan 414,4 bayta düşüyor; kullanıcı gönderisinin nerede olduğunu ve durumunu
görüyor, ücreti göremiyor.

Bir tasarım kararı burada görünür oluyor. Ücret alanı ilk altmış turda bayat sunuluyor, sonra
bayatlık sınırı aşılınca yanıttan çıkarılıyor: tabloda 127 bayat ve 840 eksik alan. Bayat bir ücret
bir süre gerçeğe yakındır, on beş dakika sonra yalnızca yanlıştır. Sınır o "bir süre"nin adıdır.

#### Yalıtımın Sınırı

AY14b tablosu bu konunun kapanış cümlesini yazıyor. İzdüşüm okuma modeli — çekirdek iki alanın tek
kaynağı — durduğunda üç politika da çöküyor. Katı politika ve alan atlama 900 isteğin 900'ünü
düşürüyor: on beş dakika kesinti, payın yüzde 53,2'si. Bayat yedek yalnız 59 isteği yanıtlıyor ve
59. turda susuyor; kesinti 14,02 dakika, payın yüzde 49,7'si.

Kazanç bir dakikadır ve o bir dakika bayatlık sınırının kendisidir. Bozulma çekirdeği taşımaz,
yalnız **erteler**. Son tablo bunu üç satırda özetliyor: isteğe bağlı bir kaynak düştüğünde yanıt
sayısı 900'de kalır, çekirdek kaynak düştüğünde 59'a iner ve son yanıt 59. turda verilir.

Buradan konunun bütünü hakkında bir şey söylenebilir. Bu konudaki her kalıp arızayı **çevreler**:
bozuk bağımlılığı devreden çıkarır, kaynak havuzlarını ayırır, denemeyi sınırlar, süreyi bütçeler,
aşırı yükü kaynağa bildirir, kapasiteyi aşan isteği reddeder, yanıtın çevresini kırpar. Hiçbiri
arızayı **kaldırmaz**. Bozulmuş parça bozulmuş kalır; tek fark, çevresindeki sistemin onunla
birlikte bozulmamasıdır.

Çekirdek bir parça bozulduğunda çevrelemenin verecek bir şeyi kalmaz. O noktada gereken tek şey
bozuk parçanın **yerine geçecek bir kopyadır** — ve bu konuda öyle bir kopya hiç tasarlanmadı.
Kopyanın nerede duracağı, ne zaman devralacağı, devralma sırasında kaç isteğin düşeceği ve devralma
kararının yanlış verilmesinin ne kadara mal olacağı açık sorulardır.

#### Özet

- Zarif bozulma yanıtın alanlarını çekirdek ve isteğe bağlı kümelere ayırır ve çekirdek varsa isteği
  yanıtlar; zarif kapanmadan ayrıdır — biri kapanan bir sürecin işini bitirmesi, öteki ayakta kalan
  bir sistemin yanıtını küçültmesidir.
- Arızasız günün bedeli üç kalemdir: yanıt başına 24 baytlık tazelik göstergesi (K01 yanıtının yüzde
  5,0'i, tepe okumada 9,77 KiB/s), 2,29 MiB'lik yedek defteri ile saniyede 1666,68 defter yazması
  ve arızasız günde bile bayat sunulan alanların yüzde 2,50'si.
- AY14a'da (isteğe bağlı bağımlılık düştü) katı politika 900 isteğin tamamını düşürür ve 15,00
  dakikayla K01'in 28,2 dakikalık arıza payının yüzde 53,2'sini yer; alan atlama bunu 0,73 dakikaya,
  bayat yedek 0,00 dakikaya indirir. Yanıtın ortalama boyu 504'ten 414,4 bayta düşer.
- Bayat yedek çekirdeği taşımaz, erteler: AY14b'de (çekirdek bağımlılık düştü) yalnız 59 istek
  yanıtlanır, kesinti 15,00 dakikadan 14,02 dakikaya iner ve kazanç tam olarak bayatlık sınırıdır.
- Bu konunun bütün kalıpları arızayı çevreler, hiçbiri onu kaldırmaz; çekirdek bir parça
  bozulduğunda çevrelemenin verecek bir şeyi kalmaz.

#### Sonraki Adım

Konunun bıraktığı boşluk tek cümleyle yazılabilir: bozulan parçanın yerine geçecek bir şey yok.
Yalıtım kalıpları arızayı bir kutuya kapattı ve kutunun dışındaki sistemi ayakta tuttu; kutunun
içindeki parça ise hâlâ bozuk ve onu düzeltecek bir mekanizma tasarlanmadı. AY14b'nin 14,02 dakikası
tam olarak bu boşluğun ölçüsüdür — çevreleme oradan sonrasına dokunamaz. Sıradaki konu kutunun
içine bakar ve ilk soruyu sorar: bozuk parçanın yerine hazır bekleyen bir kopya varsa, o kopyanın
devralması nasıl kararlaştırılır. Kararın kendisi bir arıza kaynağıdır, çünkü yavaşlamış bir parça
ile durmuş bir parça dışarıdan aynı görünür ve yanlış verilen bir devralma kararı, hiç devralmamış
olmaktan daha pahalıya mal olabilir. O konu devralma penceresini, kararın tetiklenmesini ve
devralmanın kesinti bütçesine yazdığı dakikayı ele alır.

## Kurtarma ve Süreklilik

Arıza gerçekleştikten sonraki tasarım: etkin–pasif ile etkin–etkin kurulumun devralma maliyeti üzerinden seçilmesi, sağlık ucunun otomatik devre dışı bırakmayı beslemesi, kurtarma süresi ve veri kaybı hedeflerinin sayıya çevrilerek kesinti bütçesiyle karşılaştırılması, bölge ile alan düzeyinde yedeklilik, ölçek birimlerinin damga olarak çoğaltılması ve planın tatbikatla sınanması.

### Devralma Tasarımı

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/devralma-tasarimi

Devralmanın kurulum seçiminden sonra kalan üç kararı: terfiyi tetikleyen ardışık başarısız denetim eşiğinin yanlış devralma ile algılama gecikmesi arasında sayıyla seçilmesi, geri dönüş politikasının ikinci bir geçiş penceresi doğurması, yanıt veren ama işini yapamayan kopyanın sessizce yuttuğu yazmanın sayılması ve bütün bu geçişlerin aylık kesinti bütçesinin arıza payına çevrilmesi.

Önceki konu sekiz kalıpla arızayı çevreledi: devre kesici bozuk bağımlılığı yoldan çıkardı, bölme
kalıbı havuzları ayırdı, zaman aşımı bütçesi bekleyişi sınırladı, zarif bozulma çekirdek işlevi
ayakta tuttu. Hepsinin ortak sınırı aynıydı: arıza **çevrelendi**, kaldırılmadı. Bozuk parça hâlâ
bozuktur ve yerine geçecek kopyanın nasıl devreye gireceği tasarlanmadı.

Kurulumun kendisi Sistem Tasarımına Giriş kursunda ölçüldü: etkin–pasif düzende devralma
tamamlanana kadar yazma düşer, etkin–etkin düzende devralma penceresi yoktur ama çakışan yazma
doğar. O ölçüm burada **girdidir** ve tekrarlanmaz. Bu dersin sorusu bir katman yukarıdadır:
devralma ne zaman tetiklenir, eski etkin kopya geri geldiğinde ne olur, ayakta görünüp işini
yapamayan bir kopya neden devralma tetiklemez ve bu geçişler kesinti bütçesinden kaç saniye tutar.

#### Kurulumdan Sonra Kalan Üç Karar

Kurulum seçimi bir kopyanın yazma kabul edip etmediğini söyler; geçişin kendisini tasarlamaz.
Geriye üç karar kalır.

**Tetikleme.** Kaç ardışık başarısız sağlık denetiminden sonra terfi başlatılır. Eşik 1 ise ilk
başarısız denetim geçişi başlatır; eşik 4 ise dört denetim beklenir. Denetimin **ne sorduğu** bir
sonraki dersin konusudur; bu modelde denetim yalnız "yanıt veriyor mu" sorar, yani sığdır.

**Geri dönüş.** Eski etkin kopya sağlığına kavuştuğunda etkinlik ona geri verilir mi, yoksa yeni
kopya kalıcı olarak etkin mi kalır. Geri dönüş kendi başına bir geçiştir ve kendi penceresini
üretir.

**Ayırt etme.** Yanıt veren ama işini yapamayan bir kopya nasıl görülür. Bu kopya sağlık
denetiminden geçtiği için hiçbir eşik onu yakalayamaz.

İki kopyanın aynı anda kendini etkin sanması ayrı bir sorundur; kira süresi ve iki liderli tur
Uygulama Katmanı ve Servis Etkileşimi kursunda kuruldu, burada tekrarlanmaz.

#### Düzenek

Aşağıdaki düzenek bir **modeldir**: gerçek küme, bölge ya da kapsayıcı kurulmaz. Tur soyut bir
adımdır — Sistem Tasarımına Giriş kursundaki devralma modelinin düzeni sürdürülür. Arıza takvimi
parametredir: `A` kopyası iki kez kısa süre yanıtsız kalıp kendiliğinden döner, iki kez gerçekten
durur ve bir kez **yarı düşük** olur (ayakta, sığ denetimi geçiyor, ama durum deposuna
yazamıyor). `B` kopyası modelde hep ayaktadır; bu bir sadeleştirmedir ve iki kopyanın birlikte
düşmesi hesaba katılmaz.

```js
// devralma/model.mjs — etkin-pasif devralma MODELIDIR. Tur soyut bir adimdir (M19/K01
// erisilebilirlik kaliplari dersinin duzeni); algilama esigi, terfi ve ariza pencereleri
// tur cinsinden parametrelerdir, olculmus sure degildir. Gercek kume kurulmaz.
export const TUR = 130;
export const KESIK = [[12, 12], [20, 21]];   // A yanit vermiyor ama kendiliginden donecek
export const DURDU = [[30, 75], [90, 96]];   // A gercekten durdu
export const YARI = [[100, 120]];            // A ayakta ve sig denetimi geciyor, depoya yazamiyor
const TERFI = 1;                             // varsayim: terfi bir tur surer
const GERI_ESIK = 3;                         // varsayim: geri donus icin ardisik saglikli denetim

const icinde = (t, a) => a.some(([b, c]) => t >= b && t <= c);
export const yanitVeriyor = (t) => !icinde(t, KESIK) && !icinde(t, DURDU);
export const saglam = (t) => yanitVeriyor(t) && !icinde(t, YARI);

export function kosum({ esik, geriDonus, tur: N = TUR }) {
  const s = { dusen: 0, sessiz: 0, devralma: 0, yanlis: 0, donus: 0, pencere: 0 };
  let etkin = "A", ard = 0, iyi = 0, biter = null, yon = null;

  for (let t = 1; t <= N; t += 1) {
    const yanit = etkin === "A" ? yanitVeriyor(t) : true;   // B modelde hep ayakta

    if (biter !== null) {                                    // gecis penceresi suruyor
      s.pencere += 1; s.dusen += 1;
      if (t === biter) {
        // geriye donuk siniflama: eski etkin kendiliginden dondu, devralma gereksizdi
        if (yon === "devralma" && yanitVeriyor(t + 1)) s.yanlis += 1;
        etkin = yon === "devralma" ? "B" : "A";
        biter = null; yon = null; ard = 0; iyi = 0;
      }
      continue;
    }

    if (etkin === "A" && yanit === false) {                  // sig denetim: yalniz yanit
      ard += 1;
      s.dusen += 1;
      if (ard >= esik) { biter = t + TERFI; yon = "devralma"; s.devralma += 1; }
      continue;
    }
    ard = 0;

    if (etkin === "B" && geriDonus === "otomatik") {
      iyi = yanitVeriyor(t) ? iyi + 1 : 0;
      if (iyi >= GERI_ESIK) { biter = t + TERFI; yon = "donus"; s.donus += 1; iyi = 0; continue; }
    }

    if (etkin === "A" && saglam(t) === false) s.sessiz += 1; // yazma kabul edildi, depoya gitmedi
  }
  return s;
}

export function kalipsiz(N = TUR) {           // devralma yok: A neyse o
  let dusen = 0, sessiz = 0, kabul = 0;
  for (let t = 1; t <= N; t += 1) {
    if (yanitVeriyor(t) === false) dusen += 1;
    else if (saglam(t) === false) sessiz += 1;
    else kabul += 1;
  }
  return { kabul, dusen, sessiz };
}
```

```js
// devralma/olc.mjs — tetikleme esigi ile geri donus politikasinin ayni ariza takviminde olculmesi
import { kosum, kalipsiz, TUR, KESIK, DURDU, YARI } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const uzunluk = (a) => a.reduce((t, [b, c]) => t + (c - b + 1), 0);
console.log(`${TUR} tur. A kopyasi: ${uzunluk(KESIK)} tur gecici yanitsiz, ` +
  `${uzunluk(DURDU)} tur durdu, ${uzunluk(YARI)} tur yari dusuk. B modelde hep ayakta.`);
const k = kalipsiz();
console.log(`kalipsiz duzen: kabul ${k.kabul}, dusen ${k.dusen}, sessiz kayip ${k.sessiz}`);
console.log();

console.log("esik | devralma | yanlis devralma | geri donus | gecis turu | dusen | sessiz kayip");
console.log("-----|----------|-----------------|------------|------------|-------|-------------");
for (const esik of [1, 2, 3, 4]) {
  const r = kosum({ esik, geriDonus: "otomatik" });
  console.log(`${s(esik, 4)} | ${s(r.devralma, 8)} | ${s(r.yanlis, 15)} | ${s(r.donus, 10)} | ` +
    `${s(r.pencere, 10)} | ${s(r.dusen, 5)} | ${s(r.sessiz, 12)}`);
}
console.log();

console.log("geri donus | esik | devralma | geri donus | gecis turu | dusen | etkin kopya degisimi");
console.log("-----------|------|----------|------------|------------|-------|---------------------");
for (const geriDonus of ["otomatik", "kalici"]) {
  const r = kosum({ esik: 3, geriDonus });
  console.log(`${geriDonus.padEnd(10)} | ${s(3, 4)} | ${s(r.devralma, 8)} | ${s(r.donus, 10)} | ` +
    `${s(r.pencere, 10)} | ${s(r.dusen, 5)} | ${s(r.devralma + r.donus, 20)}`);
}
```

```
130 tur. A kopyasi: 3 tur gecici yanitsiz, 53 tur durdu, 21 tur yari dusuk. B modelde hep ayakta.
kalipsiz duzen: kabul 53, dusen 56, sessiz kayip 21

esik | devralma | yanlis devralma | geri donus | gecis turu | dusen | sessiz kayip
-----|----------|-----------------|------------|------------|-------|-------------
   1 |        4 |               2 |          4 |          8 |    12 |           20
   2 |        3 |               1 |          3 |          6 |    13 |           20
   3 |        2 |               0 |          2 |          4 |    13 |           20
   4 |        2 |               0 |          2 |          4 |    15 |           20

geri donus | esik | devralma | geri donus | gecis turu | dusen | etkin kopya degisimi
-----------|------|----------|------------|------------|-------|---------------------
otomatik   |    3 |        2 |          2 |          4 |    13 |                    4
kalici     |    3 |        1 |          0 |          1 |     7 |                    1
```

#### Eşiğin İki Yüzü

Kalıpsız satır karşılaştırmanın tabanıdır: devralma olmadan 130 turun 56'sında yazma kabul edilmez.
Eşik 3 ile aynı takvimde düşen tur 13'e iner — kalıbın arızalı gündeki kazancı budur.

Eşik sütunu ödünleşimi iki yönlü gösteriyor. **Eşik küçüldükçe yanlış devralma artıyor.** Eşik 1,
kendiliğinden dönecek iki kesintiyi de geçiş olarak işledi: 4 devralmanın 2'si yanlış devralmadır,
yani eski etkin kopya terfi biter bitmez yanıt vermeye başlamıştı. Eşik 2 bunlardan birini
yakaladı, eşik 3 ve 4 hiçbirini tetiklemedi.

**Eşik büyüdükçe algılama gecikiyor.** Gerçek durmanın başladığı turdan geçişin tamamlandığı tura
kadar geçen süre eşik kadar uzar; düşen tur eşik 3'te 13, eşik 4'te 15'tir. Toplam tek yönlü
değildir: eşik 1 ile eşik 3 arasında düşen tur 12 ve 13 gibi birbirine yakın çıkıyor, çünkü eşik
1'in kazandığı algılama hızını yanlış devralmanın penceresi geri alıyor. **Eşik seçimi bir hız
kararı değil, iki maliyeti dengeleyen bir karardır**; dengenin yeri arıza takvimine bağlıdır.

Sessiz kayıp sütunu dört satırda da 20'dir. Eşik ne seçilirse seçilsin değişmiyor, çünkü yarı
düşük kopya sığ denetimi geçiyor ve sayaç hiç artmıyor.

#### Geri Dönüş İkinci Bir Penceredir

İkinci tablo aynı eşikle iki geri dönüş politikasını karşılaştırıyor. Otomatik geri dönüşte etkin
kopya dört kez değişiyor (2 devralma, 2 geri dönüş) ve geçiş turu 4; kalıcı politikada tek bir
değişim ve tek bir geçiş turu var. Düşen tur 13'ten 7'ye iniyor.

Fark iki yerden geliyor. Birincisi, her geri dönüş kendi penceresini üretir. İkincisi ve daha
önemlisi, otomatik geri dönüş sistemi **aynı kopyaya yeniden bağlar**: modelin takviminde `A`
kopyası ilk durmadan sonra geri dönüyor, etkinlik ona veriliyor ve az sonra ikinci kez duruyor.
Kalıcı politikada bu ikinci durma hiç kesinti üretmez, çünkü etkin kopya artık `B`'dir.

Otomatik geri dönüşün karşılığı işletme tarafındadır: kopyaların rolleri bilinen bir düzene döner.
Karar, ölçülen iki sayının karşılaştırılmasıdır: 6 fazla düşen tur karşılığında bilinen bir
yerleşim.

#### Yanıt Veren Ama Yazmayan Kopya

Yarı düşük pencere bu modelin en sessiz kısmıdır. Kopya ayaktadır, sağlık denetimini geçer ve istek
kabul eder — ama kabul ettiği yazma durum deposuna ulaşmaz. Kalıpsız düzende 21, kalıplı düzende
20 tur boyunca yazma **kabul edildi ve kayboldu**. Kesinti bütçesi bu turları hiç görmez, çünkü
sistem yanıt veriyordu.

#### İki Günün Sayısı

Turlar ancak bir çevrim varsayımıyla bütçeye çevrilir. Bu kursun kendi varsayımları K01'in
tablosuna eklenmez, kendi adlarıyla anılır. **KU1 — bir tur bir sağlık denetimi aralığıdır, 2
saniye.** **KU2 — ayda 2 gerçek durma**; gerekçesi K01'in arıza payının ayda 2,82 arıza
kaldırmasıdır. **KU3 — ayda 20 geçici yanıtsızlık**; gerekçesi kısa duraklamaların gerçek
durmalardan sık olmasıdır. Kurtarma süresi, tepe yazma ve arıza payı K01'den okunur.

```js
// devralma/butce.mjs — model turlarinin K01'in kesinti butcesine ve istek sayisina cevrilmesi
const TUR_SN = 2;          // KU1 (varsayim): bir tur bir saglik denetimi araligi, 2 saniye
const GERCEK_AY = 2;       // KU2 (varsayim): ayda 2 gercek durma
const KESIK_AY = 20;       // KU3 (varsayim): ayda 20 gecici yanitsizlik
const KURTARMA_SN = 600;   // K01: kurtarma suresi varsayimi 10 dakika
const ARIZA_PAYI = 28.2;   // K01: aylik kesinti butcesinin ariza payi (dakika)
const TEPE_YAZMA = 97.22;  // K01: tepe yazma istek/s
const TEPE_UC = 513.89;    // K01: tepe uctaki istek/s
const TERFI = 1;
const b = (x, n = 2) => x.toFixed(n);

console.log(`${"esik".padStart(5)}${"gecis penceresi".padStart(17)}${"gercek durma (ay)".padStart(19)}` +
  `${"yanlis devralma (ay)".padStart(22)}${"toplam kesinti".padStart(16)}${"ariza payinin".padStart(15)}`);
for (const esik of [1, 2, 3, 4]) {
  const pencere = (esik + TERFI) * TUR_SN;
  const gercek = GERCEK_AY * pencere;
  const yanlis = esik <= 2 ? KESIK_AY * (pencere + TERFI * TUR_SN) : 0;  // esik 3+ kisa kesinti tetiklemiyor
  const toplam = gercek + yanlis;
  console.log(`${String(esik).padStart(5)}${(pencere + " sn").padStart(17)}${(b(gercek, 1) + " sn").padStart(19)}` +
    `${(b(yanlis, 1) + " sn").padStart(22)}${(b(toplam / 60, 2) + " dk").padStart(16)}` +
    `${("%" + b((100 * toplam) / 60 / ARIZA_PAYI, 2)).padStart(15)}`);
}

const kalipsiz = GERCEK_AY * KURTARMA_SN;
console.log(`\nkalipsiz duzen: ayda ${GERCEK_AY} durma x ${KURTARMA_SN} sn = ${b(kalipsiz / 60, 1)} dk, ` +
  `ariza payinin %${b((100 * kalipsiz) / 60 / ARIZA_PAYI, 1)}'i`);
const esik3 = GERCEK_AY * (3 + TERFI) * TUR_SN;
console.log(`esik 3 ile ayni iki durma: ${esik3} sn, oran ${b(kalipsiz / esik3, 1)} kat kisalma`);
console.log(`pencerede dusen: ${b((3 + TERFI) * TUR_SN * TEPE_YAZMA)} yazma, ` +
  `${b((3 + TERFI) * TUR_SN * TEPE_UC)} uc istegi (tepe yukte)`);

const SESSIZ_TUR = 20;     // modelden: yari dusuk pencerede kabul edilen ama depoya gitmeyen turlar
console.log(`\nyari dusuk pencere: ${SESSIZ_TUR} tur x ${TUR_SN} sn = ${SESSIZ_TUR * TUR_SN} sn, ` +
  `${b(SESSIZ_TUR * TUR_SN * TEPE_YAZMA)} yazma sessizce kayboldu`);
console.log(`bu pencere kesinti butcesinde gorunmez: sistem yanit veriyordu`);

console.log();
for (const kopya of [2, 3]) {                 // etkin-etkin: bozuk kopya havuzun 1/k'sini tasiyor
  console.log(`etkin-etkin ${kopya} kopya: devreden cikarma penceresinde ` +
    `${b(((3 + TERFI) * TUR_SN * TEPE_YAZMA) / kopya)} yazma duser, ` +
    `yari dusuk pencerede ${b((SESSIZ_TUR * TUR_SN * TEPE_YAZMA) / kopya)} yazma sessizce kaybolur`);
}
```

```
 esik  gecis penceresi  gercek durma (ay)  yanlis devralma (ay)  toplam kesinti  ariza payinin
    1             4 sn             8.0 sn              120.0 sn         2.13 dk          %7.57
    2             6 sn            12.0 sn              160.0 sn         2.87 dk         %10.17
    3             8 sn            16.0 sn                0.0 sn         0.27 dk          %0.95
    4            10 sn            20.0 sn                0.0 sn         0.33 dk          %1.18

kalipsiz duzen: ayda 2 durma x 600 sn = 20.0 dk, ariza payinin %70.9'i
esik 3 ile ayni iki durma: 16 sn, oran 75.0 kat kisalma
pencerede dusen: 777.76 yazma, 4111.12 uc istegi (tepe yukte)

yari dusuk pencere: 20 tur x 2 sn = 40 sn, 3888.80 yazma sessizce kayboldu
bu pencere kesinti butcesinde gorunmez: sistem yanit veriyordu

etkin-etkin 2 kopya: devreden cikarma penceresinde 388.88 yazma duser, yari dusuk pencerede 1944.40 yazma sessizce kaybolur
etkin-etkin 3 kopya: devreden cikarma penceresinde 259.25 yazma duser, yari dusuk pencerede 1296.27 yazma sessizce kaybolur
```

**Arızalı günün kazancı** ilk iki satırın karşılaştırmasıdır. Devralma olmadan aynı iki durma
kurtarma süresi kadar sürer: 20,0 dakika, yani arıza payının yüzde 70,9'u. İki durma bütçenin
neredeyse tamamını yer ve ayda üçüncü bir durma hedefi kırar. Eşik 3 ile aynı iki durma 16 saniye
tutar — 75 kat kısalma — ve arıza payının yüzde 0,95'ini harcar. Bu oran koşumdan bağımsız
türetilmiş bir niceliktir; makineye değil, kurtarma süresi ile geçiş penceresinin oranına bağlıdır.

**Arızasız günün bedeli** yanlış devralma sütunundadır. Eşik 1'de ayda 20 geçici yanıtsızlık,
hiçbiri gerçek arıza olmadığı hâlde 120 saniye kesinti üretiyor; eşik 2'de 160 saniye. İki satırda
da arızasız günün bedeli arızalı günün maliyetinden büyüktür: eşik 2'de 160 saniyeye karşı 12
saniye. Eşik 3'te bedel sıfıra iner ve karşılığında gerçek durmanın penceresi 4 saniyeden 8
saniyeye çıkar. Kalıbın arızasız gündeki ikinci bedeli aritmetikte görünmez: pasif kopya bütün
kapasitesini taşır ve hiç istek yanıtlamaz.

Pencerenin tek seferlik faturası da yazılır: sekiz saniyelik bir geçişte tepe yükte 777,76 yazma ve
uçta 4.111,12 istek düşer. Kesinti bütçesi ortalamayı ölçtüğü için bu yoğunlaşmayı göstermez.

Son iki satır kurulum farkını sayıya bağlıyor. Etkin–etkin düzende geçiş penceresi hizmetin
tamamını durdurmaz, yalnız bozuk kopyanın payını düşürür: iki kopyada 388,88, üç kopyada 259,25
yazma. Aynı bölme sessiz kayıp için de geçerlidir — üç kopyalı düzende 3.888,80 yerine 1.296,27.
Etkin–etkin kurulum arızayı ucuzlatmaz, **böler**; K01'in ölçtüğü çakışan yazma bu bölmenin
karşılığıdır.

#### Özet

- Kurulum seçiminden sonra üç karar kalır: terfiyi tetikleyen eşik, eski etkin kopyaya geri dönüş
  politikası ve yanıt veren ama işini yapamayan kopyanın ayırt edilmesi.
- Eşik iki maliyeti dengeler: eşik 1 kendiliğinden dönecek iki kesintiyi de geçişe çevirdi (2
  yanlış devralma), eşik 4 algılamayı geciktirdi (15 düşen tur); toplam düşen tur 12 ile 15
  arasında dar bir aralıkta kaldı.
- Geri dönüş kendi penceresini üretir: otomatik politikada 4 geçiş ve 13 düşen tur, kalıcı
  politikada 1 geçiş ve 7 düşen tur.
- Hiçbir eşik yarı düşük kopyayı yakalamıyor: sessiz kayıp dört eşikte de 20 tur; sığ denetim
  yanıt aldığı için sayaç hiç artmıyor.
- KU1–KU3 varsayımlarıyla arızalı günün kazancı 20,0 dakikadan 16 saniyeye iniştir: 75 kat kısalma
  ve arıza payının yüzde 70,9 yerine yüzde 0,95'i.
- Arızasız günün bedeli eşik 1'de ayda 120, eşik 2'de 160 saniye yanlış devralma kesintisidir;
  eşik 3'te sıfırlanır, karşılığında geçiş penceresi 4 saniyeden 8 saniyeye çıkar.

#### Sonraki Adım

Bu dersin bütün kararları tek bir girdiye dayandı: sağlık denetiminin verdiği evet ya da hayır. O
girdi yanlış olduğunda eşik de, geri dönüş politikası da anlamını yitiriyor — modelin yarı düşük
penceresinde 3.888,80 yazma, sistem sağlıklı görünürken kayboldu. Sonraki ders denetimin
**içeriğini** tasarlar: ucun bağımlılıklarına bakıp bakmadığı, bağımlılığı denetime katmanın bütün
kopyaları birden sağlıksız işaretleme riski, trafik almaya hazır olmakla ayakta olmanın ayrılması
ve denetim aralığının algılama gecikmesi ile yanlış devralma arasında nereye oturduğu.

### Sağlık Ucu İzleme

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/saglik-ucu-izleme

Devralmayı besleyen sağlık ucunun içeriğinin tasarlanması: sığ denetim, hazır olma denetimi ve derin denetimin aynı arıza takviminde ölçülmesi, paylaşılan bir bağımlılığı denetime katmanın bütün kopyaları birden havuz dışına çıkarması, denetim aralığının algılama gecikmesi ile yanlış çıkarma arasındaki ödünleşimi ve denetimin bağımlılığa eklediği yükün sayılması.

Önceki dersin bütün kararları tek bir girdiye dayandı: sağlık denetiminin verdiği evet ya da
hayır. Eşiğin nasıl seçildiği, geri dönüşün ne zaman yapıldığı, hatta devralmanın hiç yapılıp
yapılmadığı bu tek bitin doğruluğuna bağlıydı. Modelin yarı düşük penceresinde 3.888,80 yazma,
sistem sağlıklı görünürken kayboldu — çünkü denetim yalnız "yanıt veriyor musun" diye soruyordu.

Sağlık denetiminin devralmayı ve yük dengeleyici havuzunu beslediği Veritabanı Yönetimi ve Trafik
Katmanı kurslarında kuruldu; sunum tarafındaki uç biçimi Sunucu Tarafı Temelleri kursunda tanıtıldı. Bu
ders o ucun **içeriğini** tasarlar: hangi soruyu sorduğu, bağımlılıklarını denetime katıp
katmadığı ve ne sıklıkla sorulduğu. Ucun topladığı ölçütlerin nereye gönderildiği, gösterge
tablosu ve uyarı eşiği bu kursun konusu değildir; Başarım Karşıt Kalıpları ve İzleme kursuna
aittir.

#### Ucun Sorabileceği Dört Soru

**Sığ denetim** yalnız sürecin ayakta ve yanıt verebilir olduğunu sınar. Yanıtı hiçbir
bağımlılığa dokunmadan üretir, bu yüzden ucuzdur ve yanlış negatif vermez.

**Hazır olma denetimi** ayrı bir sorudur: süreç ayakta olabilir ama trafik almaya hazır
olmayabilir. Yeni başlamış bir kopya önbelleğini doldurmamış, yapılandırmasını okumamış ya da
göçünü bitirmemiş olabilir. Ayakta olmak ile hazır olmak ayrı iki durumdur ve tek bir uçta
birleştirildiklerinde ikisinden biri kaybolur.

**Derin denetim** kopyanın bağımlılıklarına dokunur. Burada iki tür bağımlılık ayrılır ve ayrım
bu dersin ana sonucudur: kopyanın **kendi yoluna** ait bağımlılık (bu kopyanın durum deposuna
yazabilmesi) ile **paylaşılan** bağımlılık (durum deposunun ayakta olması). Birincisi kopyalar
arasında farklıdır, ikincisi hepsinde aynıdır.

Aşağıdaki düzenek bir **modeldir**: üç kopya, bir paylaşılan durum deposu ve yalnız toplu akışı
besleyen bir ücretlendirme deposu. Tur soyut bir adımdır. Tur başına gelen istek karışımı K01'in
okuma–yazma oranına yakın seçildi: 8 okuma, 2 yazma, 1 toplu.

```js
// saglik/model.mjs — saglik ucunun icerigi MODELIDIR. Uc kopya, bir paylasilan durum deposu ve
// bir akisa ozel ucretlendirme deposu; tur soyut bir adimdir, olculmus sure degildir.
export const TUR = 130;
export const K3_DURDU = 82;   // k3 bu turda durdu; algilama gecikmesi buna gore olculur
export const KOPYA = ["k1", "k2", "k3"];
const P = (t, a) => a.some(([b, c]) => t >= b && t <= c);

export const takvim = {
  yariDusuk: { k1: [[20, 45]], k2: [], k3: [] },        // yaziyor gibi gorunur, depoya gitmez
  isiniyor: { k1: [], k2: [[1, 8], [60, 66]], k3: [] }, // surec ayakta, trafige hazir degil
  durdu: { k1: [], k2: [], k3: [[82, 95]] },            // surec yanit vermiyor
  gecici: { k1: [], k2: [], k3: [[50, 50], [58, 59]] }, // kisa yanitsizlik, kendiliginden doner
  durumDeposu: [[100, 110]],                            // paylasilan bagimlilik dustu
  ucretDeposu: [[115, 125]],                            // yalniz toplu akisi etkiler
};

export const durumDeposuAyakta = (t) => !P(t, takvim.durumDeposu);
export const ucretDeposuAyakta = (t) => !P(t, takvim.ucretDeposu);
export const surecAyakta = (k, t) => !P(t, takvim.durdu[k]) && !P(t, takvim.gecici[k]);
export const isiniyor = (k, t) => P(t, takvim.isiniyor[k]);
export const yolSaglam = (k, t) => !P(t, takvim.yariDusuk[k]);   // kopyanin kendi yazma yolu
export const okuyabilir = (k, t) => surecAyakta(k, t) && !isiniyor(k, t);

// Bes uc icerigi. Her biri kopya basina tek bir evet/hayir dondurur.
export const UC = {
  sig: (k, t) => surecAyakta(k, t),
  hazirOlma: (k, t) => okuyabilir(k, t),
  derinYerel: (k, t) => okuyabilir(k, t) && yolSaglam(k, t),
  derinPaylasilan: (k, t) => okuyabilir(k, t) && yolSaglam(k, t) && durumDeposuAyakta(t),
  derinHepsi: (k, t) => okuyabilir(k, t) && yolSaglam(k, t) && durumDeposuAyakta(t)
    && ucretDeposuAyakta(t),
};

const OKUMA = 8, YAZMA = 2, TOPLU = 1;   // tur basina istek: K01'in okuma/yazma oranina yakin

export function kosum(ucAdi, { aralik = 1, tur: N = TUR } = {}) {
  const uc = UC[ucAdi];
  const s = { disKopyaTur: 0, dusenOkuma: 0, dusenYazma: 0, dusenToplu: 0, sessiz: 0,
    bosaRed: 0, denetim: 0, yanlisCikarma: 0, algilama: null };
  let sira = 0, karar = Object.fromEntries(KOPYA.map((k) => [k, true])), oncekiKarar = { ...karar };

  for (let t = 1; t <= N; t += 1) {
    if ((t - 1) % aralik === 0) {                       // denetim turu
      oncekiKarar = { ...karar };
      for (const k of KOPYA) karar[k] = uc(k, t);
      s.denetim += KOPYA.length;
      for (const k of KOPYA)                            // gecici yanitsizlik havuzdan cikardi mi
        if (oncekiKarar[k] && karar[k] === false && P(t, takvim.gecici[k])) s.yanlisCikarma += 1;
      if (s.algilama === null && karar.k3 === false && P(t, takvim.durdu.k3))
        s.algilama = t - K3_DURDU;
    }
    const havuz = KOPYA.filter((k) => karar[k]);
    s.disKopyaTur += KOPYA.length - havuz.length;
    const varOkuyan = KOPYA.some((k) => okuyabilir(k, t));

    for (let i = 0; i < OKUMA; i += 1) {
      if (havuz.length === 0) { s.dusenOkuma += 1; if (varOkuyan) s.bosaRed += 1; continue; }
      const k = havuz[sira++ % havuz.length];
      if (okuyabilir(k, t) === false) s.dusenOkuma += 1;
    }
    for (let i = 0; i < YAZMA; i += 1) {
      if (havuz.length === 0) { s.dusenYazma += 1; continue; }
      const k = havuz[sira++ % havuz.length];
      if (okuyabilir(k, t) === false) { s.dusenYazma += 1; continue; }
      if (yolSaglam(k, t) === false) { s.sessiz += 1; continue; }   // kabul edildi, depoya gitmedi
      if (durumDeposuAyakta(t) === false) s.dusenYazma += 1;
    }
    for (let i = 0; i < TOPLU; i += 1) {
      if (havuz.length === 0 || ucretDeposuAyakta(t) === false) { s.dusenToplu += 1; continue; }
      sira += 1;
    }
  }
  return s;
}
```

```js
// saglik/olc.mjs — bes uc icerigi ayni ariza takviminde, ardindan denetim araliginin etkisi
import { kosum, TUR, KOPYA } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
console.log(`${TUR} tur, ${KOPYA.length} kopya, tur basina 8 okuma + 2 yazma + 1 toplu istek.`);
console.log("takvim: k1 20-45 yari dusuk, k2 1-8 ve 60-66 isiniyor, k3 50 ve 58-59 gecici " +
  "yanitsiz, 82-95 durdu, durum deposu 100-110, ucret deposu 115-125 dusuk.");
console.log();
console.log("uc icerigi      | havuz disi | dusen okuma | dusen yazma | dusen toplu | sessiz kayip | bosa red");
console.log("----------------|------------|-------------|-------------|-------------|--------------|---------");
for (const ad of ["sig", "hazirOlma", "derinYerel", "derinPaylasilan", "derinHepsi"]) {
  const r = kosum(ad);
  console.log(`${ad.padEnd(15)} | ${s(r.disKopyaTur, 10)} | ${s(r.dusenOkuma, 11)} | ` +
    `${s(r.dusenYazma, 11)} | ${s(r.dusenToplu, 11)} | ${s(r.sessiz, 12)} | ${s(r.bosaRed, 8)}`);
}

console.log();
console.log("aralik | denetim sayisi | algilama gecikmesi | yanlis cikarma | dusen okuma | sessiz kayip");
console.log("-------|----------------|--------------------|----------------|-------------|-------------");
for (const aralik of [1, 2, 4, 8]) {
  const r = kosum("derinYerel", { aralik });
  console.log(`${s(aralik, 6)} | ${s(r.denetim, 14)} | ${s(`${r.algilama} tur`, 18)} | ` +
    `${s(r.yanlisCikarma, 14)} | ${s(r.dusenOkuma, 11)} | ${s(r.sessiz, 12)}`);
}
```

```
130 tur, 3 kopya, tur basina 8 okuma + 2 yazma + 1 toplu istek.
takvim: k1 20-45 yari dusuk, k2 1-8 ve 60-66 isiniyor, k3 50 ve 58-59 gecici yanitsiz, 82-95 durdu, durum deposu 100-110, ucret deposu 115-125 dusuk.

uc icerigi      | havuz disi | dusen okuma | dusen yazma | dusen toplu | sessiz kayip | bosa red
----------------|------------|-------------|-------------|-------------|--------------|---------
sig             |         17 |          40 |          32 |          11 |           17 |        0
hazirOlma       |         32 |           0 |          22 |          11 |           17 |        0
derinYerel      |         58 |           0 |          22 |          11 |            0 |        0
derinPaylasilan |         91 |          88 |          22 |          22 |            0 |       88
derinHepsi      |        124 |         176 |          44 |          22 |            0 |      176

aralik | denetim sayisi | algilama gecikmesi | yanlis cikarma | dusen okuma | sessiz kayip
-------|----------------|--------------------|----------------|-------------|-------------
     1 |            390 |              0 tur |              2 |           0 |            0
     2 |            195 |              1 tur |              1 |          11 |            0
     4 |             99 |              3 tur |              0 |          19 |            0
     8 |             51 |              7 tur |              0 |          40 |            3
```

#### Derinlik Nereye Kadar

İlk üç satır derinliğin kazandırdığını gösteriyor. Sığ denetim ısınmakta olan kopyayı havuzda
tuttu ve ona yönlenen 40 okuma ile 32 yazma düştü; hazır olma denetimi eklendiğinde düşen okuma
0'a, düşen yazma 22'ye indi. Kalan 22 yazma paylaşılan deponun düştüğü on bir turda oluşuyor ve
hiçbir uç içeriği onu kurtarmıyor — kopya sağlıklı olsa da yazacak yer yok.

Sütunun adı Veri Katmanı Ölçekleme kursundan gelir: **sessiz kayıp**, kabul edilmiş bir yazmanın
sahibine hiçbir şey söylenmeden geçersizleşmesidir. Orada nedeni çakışmaydı, burada yarı düşük
kopyadır; ölçü aynıdır.

Yerel derin denetim sessiz kaybı kaldırıyor: 17'den 0'a. Yarı düşük kopya artık havuzun dışında,
çünkü uç "yazabiliyor muyum" sorusuna dürüst yanıt veriyor. Bedeli havuz dışı kopya-tur sütununda:
32'den 58'e. Bu, önceki dersin çözemediği sorunun karşılığıdır ve bedeli yalnız bozuk kopyayı
havuzdan çıkarmaktır.

**Dördüncü satırda işaret dönüyor.** Paylaşılan durum deposu denetime katıldığında, depo düştüğü
anda üç kopya da aynı yanıtı veriyor ve üçü birden havuz dışına çıkıyor. Havuz boşalınca yalnız
yazma değil, **okuma da** reddediliyor: 88 düşen okuma, hepsi boşa red. Boşa red sütununun anlamı
tam olarak budur — en az bir kopya o isteği yanıtlayabilecek durumdayken reddedilen istek. Kenar
önbelleği ve kopyalardan okuma yolu ayaktaydı; denetim onları da kapattı. Düşen toplu iş de 11'den
22'ye çıktı.

Beşinci satır aynı hatayı bir kez daha yapıyor. Yalnız gün sonu ücretlendirmesini besleyen depo
denetime katıldığında, o depo düştüğünde takip sorgusu yanıtlayan kopyalar da havuz dışına
çıkıyor: boşa red 88'den 176'ya. Ücretlendirme akışının deposu ile takip sorgusunun yolu
arasında hiçbir bağ yokken, denetim ikisini birbirine bağladı.

Kural bu üç satırdan okunur: **uç, kopyanın komşularından daha kötü durumda olup olmadığını
sormalıdır, dünyanın iyi olup olmadığını değil.** Bütün kopyalarda aynı yanıtı verecek bir koşul
uca konursa, o koşul bozulduğunda havuzda kimse kalmaz ve yayılma kalıbın kendisinden gelir. Bu
yüzden paylaşılan bağımlılığın arızası devre kesici ile zarif bozulmanın konusudur — önceki
konuda ölçüldü — sağlık ucunun değil.

#### Aralık Ne Kadar Sık

İkinci tablo aynı uç içeriğini (`derinYerel`) dört denetim aralığında koşturuyor. Aralık 1'de
denetim sayısı 390, algılama gecikmesi 0 tur, düşen okuma 0 — ama iki **yanlış çıkarma** var:
kendiliğinden dönecek kısa yanıtsızlıklar kopyayı havuzdan çıkardı. Aralık 4'te yanlış çıkarma
sıfırlanıyor, karşılığında `k3` kopyasının durduğu tur 3 tur sonra fark ediliyor ve o sürede
kopyaya yönlenen 19 okuma düşüyor. Aralık 8'de gecikme 7 tura, düşen okuma 40'a çıkıyor ve yarı
düşük kopya denetimler arasında kalarak 3 sessiz kayıp üretiyor.

Ödünleşim önceki dersin eşik ödünleşimiyle aynı biçimdedir ama ayrı bir eksendir: eşik kaç
denetimin üst üste başarısız olacağını, aralık denetimlerin ne kadar seyrek olacağını belirler.
İkisi çarpılır — aralık 4 ve eşik 3, gerçek bir arızanın en kötü durumda 12 tur boyunca fark
edilmemesi demektir.

#### İki Günün Sayısı

Denetimin arızasız gündeki bedeli iki kalemden oluşur: bağımlılığa vurulan denetim yükü ve yanlış
çıkarmanın kalan kopyalara aktardığı istek. Birincisi derin denetimin doğrudan faturasıdır.

```js
// saglik/butce.mjs — denetimin arizasiz gundeki bedeli: bagimliliga vurulan denetim yuku ve
// yanlis cikarmanin kalan kopyalara aktardigi istek
const TUR_SN = 2;          // KU1 (varsayim): bir tur bir denetim araligi, 2 saniye
const DEPO = 138.89;       // K01: depoya ulasan istek/s
const TEPE_UC = 513.89;    // K01: tepe uctaki istek/s
const KESIK_AY = 20;       // KU3 (varsayim): ayda 20 gecici yanitsizlik
const b = (x, n = 2) => x.toFixed(n);

console.log(`${"kopya".padStart(6)}${"aralik".padStart(9)}${"denetim/s".padStart(12)}` +
  `${"depoya eklenen pay".padStart(20)}${"gunde denetim".padStart(15)}`);
for (const [kopya, aralik] of [[3, 1], [3, 4], [12, 1], [12, 4], [48, 1], [48, 4]]) {
  const sn = aralik * TUR_SN, hiz = kopya / sn;
  console.log(`${String(kopya).padStart(6)}${(sn + " sn").padStart(9)}${b(hiz).padStart(12)}` +
    `${("%" + b((100 * hiz) / DEPO)).padStart(20)}${Math.round(hiz * 86_400).toLocaleString("tr-TR").padStart(15)}`);
}

console.log(`\nyanlis cikarma: 3 kopyanin biri havuzdan cikinca kalan iki kopyanin her biri ` +
  `${b(TEPE_UC / 3)} yerine ${b(TEPE_UC / 2)} istek/s tasir (${b((TEPE_UC / 2) / (TEPE_UC / 3))} kat)`);
for (const aralik of [1, 2]) {
  const oran = aralik === 1 ? 2 / 3 : 1 / 3;      // modelden: 3 gecici yanitsizligin kaci yakalandi
  console.log(`aralik ${aralik}: ayda ${b(KESIK_AY * oran, 1)} yanlis cikarma, her biri en cok ` +
    `${aralik * TUR_SN} sn boyunca kapasiteyi ${b(100 / 3, 1)}% dusurur`);
}
```

```
 kopya   aralik   denetim/s  depoya eklenen pay  gunde denetim
     3     2 sn        1.50               %1.08        129.600
     3     8 sn        0.38               %0.27         32.400
    12     2 sn        6.00               %4.32        518.400
    12     8 sn        1.50               %1.08        129.600
    48     2 sn       24.00              %17.28      2.073.600
    48     8 sn        6.00               %4.32        518.400

yanlis cikarma: 3 kopyanin biri havuzdan cikinca kalan iki kopyanin her biri 171.30 yerine 256.94 istek/s tasir (1.50 kat)
aralik 1: ayda 13.3 yanlis cikarma, her biri en cok 2 sn boyunca kapasiteyi 33.3% dusurur
aralik 2: ayda 6.7 yanlis cikarma, her biri en cok 4 sn boyunca kapasiteyi 33.3% dusurur
```

Üç kopya ve iki saniyelik aralıkta derin denetim depoya saniyede 1,50 sorgu ekliyor; K01'in depoya
ulaşan 138,89 istek/s'sinin yüzde 1,08'i. Sayı kopya sayısıyla doğrusal büyüyor ve orada bir sınıra
çarpıyor: 48 kopyada aynı aralık yüzde 17,28 ek yük demektir. **Derin denetimin faturası kopya
sayısıyla ölçeklenir, iş yüküyle değil** — yani ölçekleme kararı denetim politikasını da
değiştirir. Aralığı dörde çıkarmak faturayı dörde bölüyor.

İkinci kalem yanlış çıkarmadır. Üç kopyalı bir havuzda bir kopya çıkınca kalan ikisi 171,30 yerine
256,94 istek/s taşır, yani 1,50 kat. Aralık 1 ile modelin yakaladığı yanlış çıkarma oranı üçte
ikidir; ayda 20 geçici yanıtsızlık varsayımıyla (KU3, önceki derste tanımlandı) ayda 13,3 kez
kapasitenin üçte biri iki saniyeliğine kayboluyor. Aralık 2'de sayı 6,7'ye iniyor ama her olayın
penceresi iki katına çıkıyor. Arızasız günün bedeli budur ve hiçbir arıza olmadan ödenir.

**Arızalı günün kazancı** birinci tablonun `sig` ile `derinYerel` satırları arasındadır: aynı arıza
takviminde 40 düşen okuma 0'a, 32 düşen yazma 22'ye, 17 sessiz kayıp 0'a iniyor ve boşa red 0'da
kalıyor. Aynı tablo kazancın nerede bittiğini de gösteriyor: bir adım fazla derinlik 88, iki adım
fazla derinlik 176 boşa red üretiyor.

#### Özet

- Sağlık ucu tek bir soru değildir: sığ denetim sürecin ayakta olduğunu, hazır olma denetimi
  trafik alabildiğini, derin denetim bağımlılık yolunun çalıştığını sınar.
- Hazır olma denetimi eklendiğinde ısınan kopyaya yönlenen 40 okuma ile 10 yazma kurtuldu; yerel
  derin denetim eklendiğinde sessiz kayıp 17'den 0'a indi, bedeli havuz dışı kopya-turun 32'den
  58'e çıkmasıydı.
- Paylaşılan bağımlılığı denetime katmak yayılma üretir: depo düştüğünde üç kopya da havuz dışına
  çıktı ve 88 okuma, yanıtlanabilir olduğu hâlde reddedildi; akışa özel depo da katıldığında bu
  sayı 176'ya çıktı.
- Kural: uç kopyanın komşularından kötü durumda olup olmadığını sorar; bütün kopyalarda aynı yanıtı
  verecek bir koşul uca konursa havuz boşalır.
- Denetim aralığı ayrı bir eksendir: aralık 1'de 2 yanlış çıkarma ve 0 tur gecikme, aralık 8'de 0
  yanlış çıkarma ama 7 tur gecikme, 40 düşen okuma ve 3 sessiz kayıp.
- Arızasız günün bedeli sayılır: 3 kopya ve 2 saniyelik aralıkta derin denetim depoya yüzde 1,08 ek
  yük bindirir, 48 kopyada yüzde 17,28; yanlış çıkarma ayda 13,3 kez kalan kopyaların yükünü 1,50
  katına çıkarır.

#### Sonraki Adım

Bu iki ders bir arızanın ne kadar sürede fark edildiğini ve ne kadar sürede devredildiğini saydı:
eşik, aralık, terfi ve geri dönüş turları. Sayılan şey hep aynı büyüklüktü — **kurtarmanın
süresi**. Ama önceki dersin yarı düşük penceresinde kaybolan yazmalar başka bir büyüklüktür ve bu
iki ders onu ölçemedi: sistem geri geldiğinde verinin ne kadarı geride kalmıştır? İki soru ayrı
eşikler ister ve ikisi de aynı bütçeden ödenir. Sonraki ders bu eşikleri adlandırır, yedekleme
sıklığı ile çoğaltma gecikmesine bağlayarak sayıya çevirir ve K01'in 43,2 dakikalık aylık
bütçesiyle karşılaştırır.

### Kurtarma Hedefleri

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/kurtarma-hedefleri

Kurtarma süresi hedefi ile veri kaybı hedefinin ayrı iki eşik olarak tanımlanması: veri kaybı hedefinin yedekleme aralığı ve çoğaltma gecikmesiyle kayıp olay sayısına çevrilmesi, kurtarma süresi hedefinin K01'in aylık arıza payına kaç arıza sığdırdığının hesaplanması ve veri kaybını sıfıra indirmenin arızasız günde ödediği bedelin sayılması.

Önceki iki ders bir arızanın ne kadar sürede fark edildiğini ve ne kadar sürede devredildiğini
saydı: eşik, aralık, terfi ve geri dönüş turları. Ölçülen şey hep aynı büyüklüktü, hizmetin geri
gelme süresi. Ama birinci dersin yarı düşük penceresinde kaybolan 3.888,80 yazma başka bir
büyüklüktür ve bu iki ders onu ölçemedi: sistem geri geldiğinde verinin ne kadarı geride kalmıştır?

Bu ders iki eşiği adlandırır ve birbirinden ayırır. **Kurtarma süresi hedefi** (recovery time
objective), bir arızanın başlangıcından hizmetin geri gelmesine kadar geçmesine izin verilen en
uzun süredir. **Veri kaybı hedefi** (recovery point objective), kurtarma sonrasında kabul edilen en
fazla veri kaybıdır ve zaman cinsinden yazılır: "en fazla bir dakikalık yazma".

İkisi de **eşiktir**. Sistem Tasarımına Giriş kursundaki `kurtarma süresi` bir **ölçümdür** —
gerçekleşen bir arızanın ne kadar sürdüğü; buradaki hedef ise izin verilen üst sınırdır ve tasarım
kararı olarak önceden konur. Aynı ayrım hizmet erişilebilirliğinde de vardır: ölçülen yüzde ile
hedeflenen yüzde ayrı sayılardır ve biri ötekini doğrulamaz.

#### İki Eşik Ayrı Mekanizmayla Tutulur

Kurtarma süresi hedefi **devralma** ile tutulur: algılama, terfi ve yönlendirme turlarının toplamı
hedefin altında kalmalıdır. Veri kaybı hedefi ise **veri kopyalama** ile tutulur: kurtarılan
kopyanın verisi arıza anına ne kadar yakın olduğunu belirler. Bir sistem hızlı devralıp çok veri
kaybedebilir, ya da hiç veri kaybetmeyip yavaş kurtarabilir. Bu yüzden bir kurtarma iddiası ancak
iki sayıyla birlikte anlam taşır: "sekiz saniyede devralındı" cümlesi, "ve kaç olay kayboldu"
cümlesi olmadan eksiktir.

Veri kaybı hedefini sayıya çeviren iki girdi vardır. **Yedekleme aralığı**: en kötü durumda arıza,
bir sonraki yedeklemeden hemen önce olur ve bir aralık dolusu yazma kaybolur. **Çoğaltma
gecikmesi**: eşzamansız çoğaltmada, kaynaktan çıkmış ama hedefe varmamış yazmalar kaybolur.
Çoğaltmanın mekaniği Veri Katmanı Ölçekleme kursunda kuruldu ve burada tekrarlanmaz; gecikme
burada yalnız bir girdidir.

```js
// hedef/kayip.mjs — veri kaybi hedefinin yedekleme araligi ve cogaltma gecikmesiyle sayiya
// baglanmasi. Hepsi aritmetiktir; girdileri K01'in hesaplari ve bu dersin varsayimlaridir.
const GUN = 86_400;
const OLAY_GUN = 2_800_000;            // K01: gunluk durum olayi (V3 x V4 = 400.000 x 7)
const OLAY_SN = OLAY_GUN / GUN;        // ortalama yazma hizi
const TEPE = 97.22;                    // K01: tepe yazma istek/s
const OLAY_GONDERI = 7;                // K01: gonderi basina durum olayi
const ARTIS_GB = 0.976;                // K01: gunluk veri artisi (976 MB)
const TAM_GB = 712.48;                 // K01: saklanan veri
const b = (x, n = 2) => x.toFixed(n);

console.log(`ortalama yazma ${b(OLAY_SN)} olay/s, tepe ${TEPE} olay/s`);
console.log(`${"yedekleme araligi".padStart(18)}${"en kotu kayip".padStart(15)}` +
  `${"kayip olay (ort)".padStart(18)}${"kayip olay (tepe)".padStart(19)}${"kayip gonderi".padStart(15)}`);
for (const [ad, sn] of [["24 sa", 86_400], ["6 sa", 21_600], ["1 sa", 3600], ["15 dk", 900],
  ["5 dk", 300], ["1 dk", 60]]) {
  const ort = OLAY_SN * sn, tepe = TEPE * sn;
  console.log(`${ad.padStart(18)}${(sn + " sn").padStart(15)}` +
    `${Math.round(ort).toLocaleString("tr-TR").padStart(18)}` +
    `${Math.round(tepe).toLocaleString("tr-TR").padStart(19)}` +
    `${Math.round(ort / OLAY_GONDERI).toLocaleString("tr-TR").padStart(15)}`);
}

console.log(`\n${"cogaltma gecikmesi".padStart(19)}${"veri kaybi hedefi".padStart(19)}` +
  `${"kayip olay (tepe)".padStart(19)}${"kayip gonderi".padStart(15)}`);
for (const L of [0, 0.5, 1, 5, 10]) {
  console.log(`${(b(L, 1) + " sn").padStart(19)}${(b(L, 1) + " sn").padStart(19)}` +
    `${b(TEPE * L).padStart(19)}${b((TEPE * L) / OLAY_GONDERI).padStart(15)}`);
}

console.log(`\n${"yedekleme araligi".padStart(18)}${"gunde yedek".padStart(13)}` +
  `${"30 gunde yedek".padStart(16)}${"30 gunde artimli GB".padStart(21)}${"tam yedek GB (haftalik)".padStart(24)}`);
for (const [ad, sn] of [["24 sa", 86_400], ["1 sa", 3600], ["5 dk", 300]]) {
  const gunde = GUN / sn;
  console.log(`${ad.padStart(18)}${b(gunde, 0).padStart(13)}${b(gunde * 30, 0).padStart(16)}` +
    `${b(ARTIS_GB * 30).padStart(21)}${b(TAM_GB * 5).padStart(24)}`);
}
console.log(`saklanan yedek verisi aralikla degismiyor: degisen tek sey yedek islemi sayisi`);
```

```
ortalama yazma 32.41 olay/s, tepe 97.22 olay/s
 yedekleme araligi  en kotu kayip  kayip olay (ort)  kayip olay (tepe)  kayip gonderi
             24 sa       86400 sn         2.800.000          8.399.808        400.000
              6 sa       21600 sn           700.000          2.099.952        100.000
              1 sa        3600 sn           116.667            349.992         16.667
             15 dk         900 sn            29.167             87.498          4.167
              5 dk         300 sn             9.722             29.166          1.389
              1 dk          60 sn             1.944              5.833            278

 cogaltma gecikmesi  veri kaybi hedefi  kayip olay (tepe)  kayip gonderi
             0.0 sn             0.0 sn               0.00           0.00
             0.5 sn             0.5 sn              48.61           6.94
             1.0 sn             1.0 sn              97.22          13.89
             5.0 sn             5.0 sn             486.10          69.44
            10.0 sn            10.0 sn             972.20         138.89

 yedekleme araligi  gunde yedek  30 gunde yedek  30 gunde artimli GB tam yedek GB (haftalik)
             24 sa            1              30                29.28                 3562.40
              1 sa           24             720                29.28                 3562.40
              5 dk          288            8640                29.28                 3562.40
saklanan yedek verisi aralikla degismiyor: degisen tek sey yedek islemi sayisi
```

#### Yedekleme Tek Başına Bir Hedef Tutamaz

Birinci tablo bir mertebe farkı gösteriyor. Günlük yedeklemeyle en kötü durumda 2.800.000 durum
olayı, yani bir günlük gönderi trafiğinin tamamı kaybolur; saatlik yedeklemeyle 116.667 olay ve
16.667 gönderi. Beş dakikaya inildiğinde bile 9.722 olay kaybolur. Bu sayılar bir eksikliği değil
bir **tanımı** yansıtıyor: yedekleme belirli anların kopyasıdır ve iki an arasındaki her şey
kopyanın dışındadır.

İkinci tablo aynı büyüklüğü çoğaltma tarafında veriyor ve karşılaştırma sert: bir saniyelik
gecikmede tepe yükte 97,22 olay kaybolur. Beş dakikalık yedekleme aralığının kaybı, bir saniyelik
çoğaltma gecikmesinin kaybının 300 katıdır. **Sürekli yazma alan bir akışta anlamlı bir veri kaybı
hedefi yedeklemeyle değil çoğaltmayla tutulur**; yedeklemenin işi başka bir arıza kipini
karşılamaktır — verinin yanlış içerikle üzerine yazılması, ki bu durumda çoğaltma hatayı sadakatle
kopyalar.

Üçüncü tablo yedekleme aralığını sıkmanın bedelinin nerede olmadığını gösteriyor. Artımlı
yedeklemede otuz günde saklanan veri üç aralıkta da 29,28 GB'dir, çünkü saklanan şey değişimin
kendisidir ve değişim hacmi aralıktan bağımsızdır. Haftalık tam yedeklerin 3562,40 GB'ı da
sabittir. Değişen tek sayı yedek işlemi sayısıdır: günde 1'den 288'e. Aralığı sıkmanın faturası
depolamada değil, işlem sayısında ve her işlemin gerektirdiği eşgüdümdedir.

#### Kurtarma Süresi Hedefi Bütçeye Bakar

Kurtarma süresi hedefi tek başına seçilemez, çünkü hedef ile aylık kesinti bütçesi aynı kaynağı
paylaşır. K01 bütçeyi kurdu: yüzde 99,9 hedefi aylık 43,2 dakika, bunun 15,0 dakikası planlı
işlere, kalan 28,2 dakikası arızaya. Yüzde aritmetiği burada tekrarlanmaz; bu üç sayı girdidir.

```js
// hedef/butce.mjs — kurtarma suresi hedefinin K01'in aylik kesinti butcesiyle karsilastirilmasi
// ve veri kaybi hedefini sifira indirmenin arizasiz gundeki bedeli
const ARIZA_PAYI = 28.2;      // K01: aylik butcenin ariza payi (dakika)
const AYLIK = 43.2;           // K01: %99,9 icin aylik kesinti butcesi (dakika)
const TEPE_UC = 513.89;       // K01: tepe uctaki istek/s
const TEPE_YAZMA = 97.22;     // K01: tepe yazma istek/s
const OLAY_GUN = 2_800_000;   // K01: gunluk durum olayi
const b = (x, n = 2) => x.toFixed(n);

console.log(`${"kurtarma suresi hedefi".padStart(23)}${"ariza payina sigan".padStart(20)}` +
  `${"bir arizanin butce payi".padStart(25)}${"pencerede dusen uc istegi".padStart(27)}`);
for (const [ad, dk] of [["8 sn (devralma)", 8 / 60], ["5 dk", 5], ["10 dk", 10], ["30 dk", 30],
  ["60 dk", 60]]) {
  console.log(`${ad.padStart(23)}${b(ARIZA_PAYI / dk).padStart(20)}` +
    `${("%" + b((100 * dk) / AYLIK)).padStart(25)}` +
    `${Math.round(dk * 60 * TEPE_UC).toLocaleString("tr-TR").padStart(27)}`);
}
console.log(`K01'in kurtarma suresi varsayimi 10 dk idi ve ariza payina 2,82 ariza sigiyordu`);

console.log(`\nveri kaybi hedefini sifira indirmenin bedeli (senkron onay):`);
console.log(`  her yazma bir ek onay turu bekler -> gunde ${OLAY_GUN.toLocaleString("tr-TR")} ek tur`);
const PENCERE = 8;            // 01. ders: esik 3 ile devralma penceresi (saniye)
const DURMA_AY = 2;           // KU2 (varsayim): ayda 2 gercek durma, kopya basina
const GERILIK = 1;            // KU6 (varsayim): eszamansiz cogaltma gerikligi 1 saniye
const senkron = DURMA_AY * PENCERE * TEPE_YAZMA;
const eszamansiz = DURMA_AY * GERILIK * TEPE_YAZMA;
console.log(`  yazma yolu iki kopyaya birden baglanir: yedek kopyanin ${PENCERE} sn'lik penceresinde`);
console.log(`  ayda ${b(senkron)} yazma gorunur bicimde duser (tasiyici yeniden gonderebilir)`);
console.log(`  eszamansiz duzende ayda ${b(eszamansiz)} olay sessizce kaybolur (geri getirilemez)`);
console.log(`  oran ${b(senkron / eszamansiz)}: senkron secim daha cok istegi reddeder, daha az veri kaybeder`);
```

```
 kurtarma suresi hedefi  ariza payina sigan  bir arizanin butce payi  pencerede dusen uc istegi
        8 sn (devralma)              211.50                    %0.31                      4.111
                   5 dk                5.64                   %11.57                    154.167
                  10 dk                2.82                   %23.15                    308.334
                  30 dk                0.94                   %69.44                    925.002
                  60 dk                0.47                  %138.89                  1.850.004
K01'in kurtarma suresi varsayimi 10 dk idi ve ariza payina 2,82 ariza sigiyordu

veri kaybi hedefini sifira indirmenin bedeli (senkron onay):
  her yazma bir ek onay turu bekler -> gunde 2.800.000 ek tur
  yazma yolu iki kopyaya birden baglanir: yedek kopyanin 8 sn'lik penceresinde
  ayda 1555.52 yazma gorunur bicimde duser (tasiyici yeniden gonderebilir)
  eszamansiz duzende ayda 194.44 olay sessizce kaybolur (geri getirilemez)
  oran 8.00: senkron secim daha cok istegi reddeder, daha az veri kaybeder
```

Tablo hedefin bütçeyle nasıl konuştuğunu gösteriyor. On dakikalık bir kurtarma süresi hedefi arıza
payına 2,82 arıza sığdırıyor — K01'in vardığı sayı budur ve burada yeniden hesaplanmıyor, yalnız
öteki hedeflerin yanına konuyor. Otuz dakikalık bir hedef 0,94 arıza demektir: **tek bir arıza aylık
bütçenin yüzde 69,44'ünü yer ve ikincisi hedefi kırar.** Altmış dakikada bir arıza bütçenin yüzde
138,89'unu tutar, yani hedef tek arızayla zaten kırılmıştır. Bir kurtarma süresi hedefi
erişilebilirlik hedefinden bağımsız seçilemez; ikisi aynı bütçeye bağlıdır.

Üstteki satır önceki iki dersin kazancını bu ölçeğe koyuyor. Devralmayla ölçülen sekiz saniyelik
pencere arıza payına 211,50 arıza sığdırıyor ve tek bir arıza bütçenin yüzde 0,31'ini tutuyor.
Otomatik devralma bu yüzden bir hız iyileştirmesi değil, hedefin **karşılanabilir** hâle gelmesidir:
elle kurtarma varsayımıyla ayda üç arıza hedefi kırarken, devralmayla iki yüz arıza sığıyor.

#### İki Günün Sayısı

Veri kaybı hedefini sıfıra indirmenin yolu senkron onaydır: yazma, ikinci kopya onaylamadan kabul
edilmiş sayılmaz. **Arızasız günün bedeli** iki kalemdir. Birincisi her yazmanın bir ek onay turu
beklemesidir — günde 2.800.000 ek tur, hiçbir arıza olmadan. İkincisi ve daha keskini yazma
yolunun iki kopyaya birden bağlanmasıdır: artık **yedek** kopyanın arızası da yazmayı durdurur.
Yedek kopyanın sekiz saniyelik penceresi ayda iki kez yaşanırsa 1.555,52 yazma reddedilir.

**Arızalı günün kazancı** aynı bloğun son iki satırındadır. Eşzamansız düzende bir saniyelik
gerikliğe karşılık ayda 194,44 durum olayı sessizce kaybolur ve geri getirilemez. Senkron düzen bu
sayıyı sıfırlar. Oran 8,00: senkron seçim, kaybolan her bir olay yerine sekiz isteği açıkça
reddeder. Bu değişim gönderi takip servisinde savunulabilir, çünkü reddedilen bir durum bildirimini
taşıyıcı yeniden gönderebilir, kaybolan bir durum bildirimini kimse geri getiremez. K01'in iki
kalıbı ayırdığı yer de burasıydı: aynı arıza kesinti olarak da ödenebilir, kaybolan veri olarak da.

Karar akış başına verilir. Takip sorgusu okumadır ve veri kaybı hedefi onu ilgilendirmez. Durum
olayı için sıfır veri kaybı hedefi savunulabilir. Gün sonu ücretlendirmesi ise dört saatlik bir
pencerede çalışır ve yeniden başlatılabilir; onun için kurtarma süresi hedefi de veri kaybı hedefi
de gevşektir — yeter ki girdi olan durum olayları eksiksiz olsun.

#### Özet

- Kurtarma süresi hedefi ile veri kaybı hedefi ayrı eşiklerdir ve ayrı mekanizmalarla tutulur:
  birincisi devralmayla, ikincisi veri kopyalamayla; bir kurtarma iddiası iki sayı olmadan eksiktir.
  İkisi de eşiktir, ölçüm değildir: K01'in `kurtarma süresi` gerçekleşen bir arızanın süresidir,
  buradaki hedef izin verilen üst sınırdır.
- Yedekleme aralığı veri kaybını doğrudan belirler: günlük yedekle en kötü durumda 2.800.000 olay,
  saatlikle 116.667, beş dakikalıkla 9.722 olay kaybolur.
- Bir saniyelik çoğaltma gecikmesinin kaybı 97,22 olaydır — beş dakikalık yedekleme aralığının
  300'de biri; sürekli yazma alan bir akışta veri kaybı hedefi çoğaltmayla tutulur.
- Yedekleme aralığını sıkmanın faturası depolamada değildir: otuz günde saklanan artımlı veri üç
  aralıkta da 29,28 GB; değişen tek sayı günde 1'den 288'e çıkan yedek işlemi sayısıdır.
- Kurtarma süresi hedefi bütçeye bağlıdır: 30 dakikalık hedef arıza payına 0,94 arıza sığdırır (bir
  arıza bütçenin yüzde 69,44'ü), devralmayla ölçülen 8 saniyelik pencere 211,50 arıza sığdırır.
- Veri kaybını sıfırlamanın arızasız gündeki bedeli günde 2.800.000 ek onay turu ve ayda 1.555,52
  reddedilen yazmadır; karşılığında ayda 194,44 kalıcı kayıp ortadan kalkar (oran 8,00).

#### Sonraki Adım

Bu dersin bütün hesapları tek bir örtük varsayım taşıdı: kurtarılacak bir kopya vardır ve o kopya
arızadan etkilenmemiştir. İki kopya aynı rafta, aynı elektrik hattında ya da aynı ağ anahtarının
arkasındaysa varsayım tutmaz — K01'in kopya aritmetiğinin bir üst sınır olmasının nedeni buydu ve
orada "kopyaların bağımsız düştüğü" varsayımı açıkça işaretlenmişti. Sonraki ders kopyaların
**nereye** konduğunu ele alır: yerleşim biriminin tanımı, bir birimin kaybında ayakta kalan
kapasite, birimler arası çoğaltmanın kaybettiği yayılmamış yazma ve yedekliliği bir düzey
yukarı taşımanın arızasız günde ne kadar tuttuğu.

### Yedeklilik Bölgeleri

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/yedeklilik-bolgeleri

Kopyaların nereye konduğunun ölçülmesi: alan ile bölgenin yerleşim birimi olarak ayrılması, üç yerleşim planının makine, alan ve bölge kaybında ayakta kalan kapasite ve kaybolan yayılmamış yazma üzerinden karşılaştırılması, bir birim kaybına dayanmak için boşta tutulması gereken kapasitenin hesaplanması ve bölgeler arası çoğaltmanın arızasız günde taşıdığı ek yükün sayılması.

Önceki dersin bütün hesapları tek bir örtük varsayım taşıdı: kurtarılacak bir kopya vardır ve o
kopya arızadan etkilenmemiştir. K01 bu varsayımı zaten işaretlemişti — kopya aritmetiği ancak
kopyalar **bağımsız düştüğünde** geçerlidir ve bu yüzden hesaplanan sayı bir üst sınırdır. İki kopya
aynı elektrik hattına, aynı ağ anahtarına ya da aynı soğutma birimine bağlıysa bağımsızlık yoktur;
biri düştüğünde öteki de düşer.

Bu ders kopyaların **nereye** konduğunu ölçer. İki yerleşim birimi ayrılır. **Alan** (availability
zone), kendi güç ve ağ yolu olan, bir arızanın komşusuna geçmediği varsayılan bir yerleşim
birimidir. **Bölge** (region), coğrafi olarak ayrı bir alanlar kümesidir; iki bölge arasındaki
uzaklık yayılma turunu uzatır.

Bu kursta `alan` sözcüğü yalnız bu fiziksel yerleşim birimini karşılar. Alan Odaklı Tasarım
kursundaki `alan` (domain) bir bilgi sınırıdır, kayıt `alan`ı (field) bir veri parçasıdır; üçü ayrı
kavramlardır ve burada karışmaz. Aynı nedenle bir arızanın dokunduğu bileşen kümesi bu kursta
**bulaşma kapsamı** diye anılır, "etki alanı" diye değil.

#### Yerleşim Planı Bir Arıza Kipini Seçer

Bir yerleşim planı hangi kopyaların **birlikte** düşeceğini belirler. Altı kopya tek bir alanda
duruyorsa, o alanın kaybı altı kopyayı birden alır ve altı kopyanın hiçbir anlamı kalmaz. Aynı altı
kopya üç alana dağıtılırsa bir alanın kaybı ikisini alır. İki bölgeye dağıtılırsa bir bölgenin
kaybı üçünü alır.

Aşağıdaki düzenek bir **modeldir**: gerçek bölge, alan, bulut ortamı ya da kapsayıcı kurulmaz.
Kopyalar bölge ve alan etiketi taşıyan nesnelerdir, tur soyut bir adımdır ve yayılma turu uzaklığa
göre değişir. Çoğaltmanın mekaniği Veri Katmanı Ölçekleme kursunda kuruldu ve burada
tekrarlanmaz; buradaki tek soru bir birim kaybolduğunda **hangi yazmanın hiçbir yerde kalmadığıdır.**

**KU7 — yayılma turları: aynı alan içinde 1, aynı bölgede farklı alan arasında 2, bölgeler arasında
4 tur.** Gerekçe: yayılma süresi uzaklıkla artar. Duyarlılığı doğrusaldır; uzak turu iki katına
çıkarsa bölge kaybındaki yayılmamış yazma da iki katına çıkar. Bu varsayım K01'in tablosuna
eklenmez.

```js
// bolge/model.mjs — yerlesim MODELIDIR: kopyalar bolge ve alan etiketi tasir, yayilma turu
// uzakliga gore degisir. Tur soyut bir adimdir; gercek bolge, alan ya da bulut ortami kurulmaz.
export const TUR = 40, ARIZA_TURU = 20, TUR_YAZMA = 6;
export const YAYILMA = { alan: 1, bolge: 2, uzak: 4 };   // KU7 (varsayim): yayilma turlari

export const PLAN = {
  "tek-alan":  [["b1", "a1"], ["b1", "a1"], ["b1", "a1"], ["b1", "a1"], ["b1", "a1"], ["b1", "a1"]],
  "uc-alan":   [["b1", "a1"], ["b1", "a1"], ["b1", "a2"], ["b1", "a2"], ["b1", "a3"], ["b1", "a3"]],
  "iki-bolge": [["b1", "a1"], ["b1", "a2"], ["b1", "a3"], ["b2", "a1"], ["b2", "a2"], ["b2", "a3"]],
};
export const SENARYO = {
  makine: (y, i) => i === 0,
  alan: (y) => y[0] === "b1" && y[1] === "a1",
  bolge: (y) => y[0] === "b1",
};

const gecikme = (x, y) => (x[0] !== y[0] ? YAYILMA.uzak : x[1] !== y[1] ? YAYILMA.bolge : YAYILMA.alan);

export function kosum(planAdi, senaryoAdi) {
  const yer = PLAN[planAdi], n = yer.length;
  const dusuk = yer.map((y, i) => SENARYO[senaryoAdi](y, i));
  const canli = (i, t) => !(dusuk[i] && t >= ARIZA_TURU);
  const yazmalar = [];
  let sira = 0, s = { kabul: 0, dusen: 0, kayip: 0 };

  for (let t = 1; t <= TUR; t += 1) {
    for (const w of yazmalar) {                       // varan yayilimlar hedefte gorunur oldu
      for (const m of w.ucus) if (m.varir === t) w.sahip.add(m.hedef);
      w.ucus = w.ucus.filter((m) => m.varir > t);
    }
    if (t === ARIZA_TURU) {                            // dusen birim: sahiplik ve ucus kaybi
      for (const w of yazmalar) {
        w.ucus = w.ucus.filter((m) => canli(m.kaynak, t) && canli(m.hedef, t));
        const kalan = [...w.sahip].filter((i) => canli(i, t));
        if (kalan.length === 0 && w.ucus.length === 0) { s.kayip += 1; w.kayboldu = true; }
        w.sahip = new Set(kalan);
      }
    }
    const havuz = yer.map((_, i) => i).filter((i) => canli(i, t));
    for (let k = 0; k < TUR_YAZMA; k += 1) {
      if (havuz.length === 0) { s.dusen += 1; continue; }
      const i = havuz[sira++ % havuz.length];
      s.kabul += 1;
      const w = { sahip: new Set([i]), ucus: [], kayboldu: false };
      for (const j of havuz) if (j !== i) w.ucus.push({ kaynak: i, hedef: j, varir: t + gecikme(yer[i], yer[j]) });
      yazmalar.push(w);
    }
  }
  const ayakta = yer.filter((_, i) => canli(i, TUR)).length;
  return { ...s, ayakta, toplam: n };
}
```

```js
// bolge/olc.mjs — uc yerlesim plani, uc arizada: ayakta kalan kopya, dusen istek, kayip yazma
import { kosum, PLAN, SENARYO, TUR, ARIZA_TURU, TUR_YAZMA, YAYILMA } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
console.log(`${TUR} tur, tur basina ${TUR_YAZMA} yazma, ariza ${ARIZA_TURU}. turda.`);
console.log(`yayilma turlari: ayni alan ${YAYILMA.alan}, ayni bolge farkli alan ${YAYILMA.bolge}, ` +
  `farkli bolge ${YAYILMA.uzak} (KU7)`);
console.log();
console.log("plan       | ariza  | ayakta kopya | ayakta kapasite | dusen yazma | kayip yayilmamis");
console.log("-----------|--------|--------------|-----------------|-------------|-----------------");
for (const plan of Object.keys(PLAN)) {
  for (const senaryo of Object.keys(SENARYO)) {
    const r = kosum(plan, senaryo);
    console.log(`${plan.padEnd(10)} | ${senaryo.padEnd(6)} | ${s(`${r.ayakta}/${r.toplam}`, 12)} | ` +
      `${s(`%${((100 * r.ayakta) / r.toplam).toFixed(1)}`, 15)} | ${s(r.dusen, 11)} | ${s(r.kayip, 16)}`);
  }
}
```

```
40 tur, tur basina 6 yazma, ariza 20. turda.
yayilma turlari: ayni alan 1, ayni bolge farkli alan 2, farkli bolge 4 (KU7)

plan       | ariza  | ayakta kopya | ayakta kapasite | dusen yazma | kayip yayilmamis
-----------|--------|--------------|-----------------|-------------|-----------------
tek-alan   | makine |          5/6 |           %83.3 |           0 |                0
tek-alan   | alan   |          0/6 |            %0.0 |         126 |              114
tek-alan   | bolge  |          0/6 |            %0.0 |         126 |              114
uc-alan    | makine |          5/6 |           %83.3 |           0 |                0
uc-alan    | alan   |          4/6 |           %66.7 |           0 |                2
uc-alan    | bolge  |          0/6 |            %0.0 |         126 |              114
iki-bolge  | makine |          5/6 |           %83.3 |           0 |                1
iki-bolge  | alan   |          5/6 |           %83.3 |           0 |                1
iki-bolge  | bolge  |          3/6 |           %50.0 |           0 |                9
```

#### Üç Planın Okunması

Makine satırları üç planda da aynı: bir kopyanın kaybı hiçbir düzende hizmeti durdurmuyor. Kopya
sayısı bu arıza kipini zaten karşılıyordu ve yerleşim planı burada bir şey değiştirmiyor.

**Alan satırı planları ayırıyor.** Tek alan düzeninde alanın kaybı altı kopyayı da alıyor: 126
yazma düşüyor ve 114 yazma hiçbir yerde kalmıyor. Aynı arıza üç alanlı düzende dört kopyayı ayakta
bırakıyor, hiçbir yazma düşmüyor ve yalnız 2 yazma kayboluyor. Altı kopyanın altısı da vardı; fark
yalnız nereye konduklarındaydı.

**Bölge satırı ikinci düzeyi ayırıyor.** Üç alanlı düzen alan kaybını karşılıyor ama bölgenin kaybı
onu da tamamen alıyor — üç alanın üçü de aynı bölgededir. Yalnız iki bölgeli düzen bölge kaybında
ayakta kalıyor: yarım kapasite, sıfır düşen yazma, 9 kaybolan yayılmamış yazma.

**Dağıtmanın kendi bedeli son sütunda görünüyor.** İki bölgeli düzende tek bir makinenin kaybı bile
1 yazma kaybettiriyor, oysa tek alan düzeninde 0. Sebep yayılma turudur: kopyalar birbirinden uzağa
konduğunda bir yazmanın ikinci bir kopyaya ulaşması daha uzun sürer ve o pencerede daha çok yazma
tek bir kopyada durur. **Yayılmanın uzaması yedekliliğin karşı yüzüdür**; aynı sayı bölge kaybında
9'a çıkıyor.

#### Ne Kadar Kapasite Boşta Durmalı

Ayakta kalan kapasite sütunu bir soruyu açık bırakıyor: yüzde 66,7 kapasite yükü taşımaya yeter mi?
Yetmesi için normal günde kapasitenin bir kısmının boşta durması gerekir. Aşağıdaki hesap bu payı
alan sayısına göre veriyor ve bölgeler arası çoğaltmanın arızasız günde taşıdığı yükü sayıyor.

```js
// bolge/kapasite.mjs — yedekliligin arizasiz gundeki bedeli: bosta duran kapasite ve bolgeler
// arasi tasinan yazma; model turlarinin K01 olcegine cevrilmesi
const TEPE_UC = 513.89;       // K01: tepe uctaki istek/s
const TEPE_YAZMA = 97.22;     // K01: tepe yazma istek/s
const OLAY_GUN = 2_800_000;   // K01: gunluk durum olayi
const ARTIS_GB = 0.976;       // K01: gunluk veri artisi
const TUR_SN = 2;             // KU1 (varsayim): bir tur 2 saniye
const b = (x, n = 2) => x.toFixed(n);

console.log(`${"alan".padStart(5)}${"alan basina yuk".padStart(17)}${"bir alan dusunce".padStart(18)}` +
  `${"saglanmasi gereken".padStart(20)}${"bosta duran".padStart(13)}${"fazladan pay".padStart(14)}`);
for (const n of [2, 3, 4, 6]) {
  const normal = TEPE_UC / n, kayipta = TEPE_UC / (n - 1), toplam = n * kayipta;
  console.log(`${String(n).padStart(5)}${b(normal).padStart(17)}${b(kayipta).padStart(18)}` +
    `${b(toplam).padStart(20)}${b(toplam - TEPE_UC).padStart(13)}${("%" + b(100 * (toplam / TEPE_UC - 1), 1)).padStart(14)}`);
}

const bayt = (ARTIS_GB * 1e9) / OLAY_GUN;
console.log(`\nolay basina ${b(bayt)} bayt (K01: gunde ${ARTIS_GB} GB / ${OLAY_GUN.toLocaleString("tr-TR")} olay)`);
console.log(`iki bolgeye cogaltma: tepe yukte ${b(TEPE_YAZMA * bayt / 1024)} KB/s ek tasima, ` +
  `gunde ${b(ARTIS_GB * 1000)} MB`);

console.log(`\nkayip yayilmamis yazmanin K01 olcegine cevrilmesi (KU1: tur = ${TUR_SN} sn):`);
for (const [ad, tur, pay] of [["alan kaybi (3 alan)", 1, 3], ["bolge kaybi (2 bolge)", 4, 2]]) {
  console.log(`  ${ad.padEnd(22)} yayilma ${tur} tur = ${tur * TUR_SN} sn, ` +
    `birim basina ${b(TEPE_YAZMA / pay)} yazma/s -> ${b((tur * TUR_SN * TEPE_YAZMA) / pay)} yazma`);
}
console.log(`  oran ${b(((4 * TUR_SN * TEPE_YAZMA) / 2) / ((1 * TUR_SN * TEPE_YAZMA) / 3))}: ` +
  `bolge kaybi ayni ariza suresinde daha cok yayilmamis yazma birakir`);
```

```
 alan  alan basina yuk  bir alan dusunce  saglanmasi gereken  bosta duran  fazladan pay
    2           256.94            513.89             1027.78       513.89        %100.0
    3           171.30            256.94              770.84       256.95         %50.0
    4           128.47            171.30              685.19       171.30         %33.3
    6            85.65            102.78              616.67       102.78         %20.0

olay basina 348.57 bayt (K01: gunde 0.976 GB / 2.800.000 olay)
iki bolgeye cogaltma: tepe yukte 33.09 KB/s ek tasima, gunde 976.00 MB

kayip yayilmamis yazmanin K01 olcegine cevrilmesi (KU1: tur = 2 sn):
  alan kaybi (3 alan)    yayilma 1 tur = 2 sn, birim basina 32.41 yazma/s -> 64.81 yazma
  bolge kaybi (2 bolge)  yayilma 4 tur = 8 sn, birim basina 48.61 yazma/s -> 388.88 yazma
  oran 6.00: bolge kaybi ayni ariza suresinde daha cok yayilmamis yazma birakir
```

Boşta duran kapasite alan sayısıyla hızla azalıyor. İki alanda bir alanın kaybına dayanmak
kapasitenin iki katını gerektirir: 513,89 istek/s taşımak için 1027,78 sağlanır ve yarısı boşta
durur. Üç alanda fazladan pay yüzde 50'ye, dört alanda yüzde 33,3'e, altı alanda yüzde 20'ye
iner. Genel biçimi $n$ alan için $1/(n-1)$'dir. **Alan sayısını artırmak yedekliliği ucuzlatır** ve
bu, aynı hizmet erişilebilirliğine iki farklı fiyatla ulaşılabileceği anlamına gelir.

Bölgeler arası çoğaltmanın taşıma faturası ise küçük: olay başına 348,57 bayt, tepe yükte 33,09
KB/s, günde 976 MB. Bu akış için bölge yedekliliğinin faturası taşımada değil, kapasitede ve
kaybolan yazmadadır. Farklı bir yükte — büyük gövdeli yazmalar taşıyan bir akışta — sıralama tersine
dönerdi; sayı akışa bağlıdır, ilkeye değil.

Son blok model turlarını K01 ölçeğine çeviriyor. Üç alanlı düzende bir alanın kaybında yayılmamış
yazma 64,81; iki bölgeli düzende bir bölgenin kaybında 388,88. Oran 6,00 ve iki nedenden geliyor:
bölgeler arası yayılma dört kat uzun ve bölge başına yazma payı daha büyük. **Bölge yedekliliği
kesintiyi kaldırır ama veri kaybını büyütür** ve bu tam olarak önceki dersin veri kaybı hedefiyle
karşılaştırılacak sayıdır: bir saniyelik çoğaltma gecikmesi 97,22 olay kaybettiriyordu, bölge
kaybı 388,88.

#### İki Günün Sayısı

**Arızasız günün bedeli** üç kalemdir. Üç alanlı bir yerleşimde kapasitenin yüzde 50'si boşta durur
— 256,95 istek/s hiçbir zaman kullanılmaz. İki bölgeli çoğaltma her yazmayı ikinci kez taşır: günde
976 MB ve tepe yükte 33,09 KB/s. Üçüncüsü, yayılmanın uzaması küçük arızalarda bile kayıp üretir:
tek makine kaybında iki bölgeli düzen 1 yazma kaybederken tek alan düzeni 0 kaybediyordu.

**Arızalı günün kazancı** aynı tablonun alan ve bölge satırlarındadır. Tek alan düzeninde bir alanın
kaybı 126 yazma düşürüp 114 yazma kaybettirirken, üç alanlı düzende aynı arıza 0 düşen yazma ve 2
kayıp veriyor. Bölge kaybında üç alanlı düzen 126/114 verirken iki bölgeli düzen 0/9 veriyor. Her
düzey bir arıza kipini kaldırıyor ve bir üstekini açıkta bırakıyor; yerleşim kararı hangi kipin
kaldırılacağını seçmektir.

#### Özet

- Alan, kendi güç ve ağ yolu olan bir yerleşim birimidir; bölge, coğrafi olarak ayrı bir alanlar
  kümesidir. Bu kursta `alan` yalnız bu anlamdadır; bilgi sınırı olan `alan` ve kayıt `alan`ı ayrı
  kavramlardır.
- Yerleşim planı hangi kopyaların birlikte düşeceğini belirler: altı kopya tek alanda toplanınca
  alan kaybı 126 yazma düşürüp 114 yazma kaybettiriyor, üç alana dağılınca aynı arıza 0 düşen yazma
  ve 2 kayıp veriyor.
- Bölge kaybı yalnız iki bölgeli düzende karşılanıyor: yüzde 50 kapasite, 0 düşen yazma, 9 kaybolan
  yayılmamış yazma.
- Dağıtmanın kendi bedeli yayılma turunun uzamasıdır: iki bölgeli düzen tek makine kaybında bile 1
  yazma kaybediyor, tek alan düzeni 0.
- Bir alan kaybına dayanmak için boşta tutulması gereken kapasite $1/(n-1)$'dir: iki alanda yüzde
  100, üç alanda yüzde 50, altı alanda yüzde 20.
- K01 ölçeğinde alan kaybı 64,81, bölge kaybı 388,88 yayılmamış yazma bırakıyor (oran 6,00); bölge
  yedekliliği kesintiyi kaldırırken veri kaybı hedefini zorlar.

#### Sonraki Adım

Bu ders kopyaları dağıttı ama dağıtılan şey hep aynı bütündü: altı kopya, tek bir hizmet, tek bir
veri kümesi. Bir alan ya da bölge kaybında ayakta kalan kapasite yüzde 66,7 ve yüzde 50 çıktı,
çünkü kaybedilen birim hizmetin bir **kesirini** taşıyordu. Bu kesir hesabı bir şeyi varsayıyor:
birimler birbirinden bağımsız iş yapabiliyor. Oysa çoğu düzende birimlerin ortak bir noktası kalır
— tek bir yönlendirme eşlemesi, tek bir numara dağıtıcısı, tek bir yapılandırma kaynağı — ve o
noktanın kaybı bütün birimleri birden alır. Sonraki ders hizmeti kendi kendine yeten yinelenebilir
birimlere bölmeyi ele alır: birim içindeki bağların birimi geçmemesi, birim başına düşen yük ve
birimler arasında paylaşılan tek kaynağın bulaşma kapsamı.

### Dağıtım Damgaları ve Coğrafi Kopyalar

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/dagitim-damgalari-ve-cografi-kopyalar

Hizmetin kendi kendine yeten yinelenebilir birimlere bölünmesi: damga sınırını geçen bağların sayılması, her bileşenin bulaşma kapsamının üç yerleşimde karşılaştırılması, damgalar arasında paylaşılan tek kaynağın kapsamının damga sayısından bağımsız kalması ve damga başına düşen yükün K01 sayılarına çevrilmesi.

Önceki ders kopyaları alanlara ve bölgelere dağıttı, ama dağıtılan şey hep aynı bütündü: tek bir
hizmet, tek bir veri kümesi. Bir birimin kaybında ayakta kalan kapasitenin yüzde 66,7 ya da yüzde
50 çıkması, kaybedilen birimin hizmetin bir **kesirini** taşıdığını varsayıyordu. Çoğu düzende bu
varsayım tutmaz: birimlerin ortak bir noktası kalır ve o noktanın kaybı hepsini birden alır.

**Dağıtım damgası** (deployment stamp), hizmetin kendi kendine yeten ve yinelenebilir bir
kopyasıdır: uygulama, deposu, önbelleği ve kuyruğu bir arada. Aynı yapı bir ölçekleme birimi olarak
kullanıldığında **ölçek birimi** adını alır — kapasite artırmak yeni bir damga açmaktır. Terim,
Uygulama Katmanı ve Servis Etkileşimi kursundaki `sürüm damgası` ile karışmaz; o, bir kaydın hangi
sürümde yazıldığını gösteren bir işarettir, bu ise bir dağıtım birimidir.

#### Damga Sınırı Nedir

Bir damga ancak sınırını geçen bağ yoksa kendi kendine yeter. Sınırı geçen her bağ, damganın
dışındaki bir şeyin ayakta olmasını gerektirir ve o şey düştüğünde damganın bağımsızlığı biter.
Bu yüzden bu dersin birinci ölçüsü **damgayı geçen bağ sayısıdır**.

Aşağıdaki düzenek bir **modeldir**: dokuz bileşen, üç akış ve üç yerleşim. Bileşenler damga içi ya
da damgalar arası paylaşılan olarak etiketlenir; akış, sırayla dokunduğu bileşenlerin listesidir.
Gerçek küme, bölge ya da kapsayıcı kurulmaz.

```js
// damga/model.mjs — dagitim damgasi MODELIDIR: bilesenler damga ici ya da damgalar arasi
// paylasilan olarak etiketlenir, akislar bilesen dizisidir. Gercek kume kurulmaz.
export const DAMGA = 4;
export const AKIS = {                          // her akisin sirayla dokundugu bilesenler
  takip: ["yonlendirme", "uc", "takip-servisi", "onbellek", "durum-deposu"],
  olay: ["yonlendirme", "uc", "olay-kuyrugu", "durum-deposu", "numara-dagitici"],
  ucret: ["ucret-isi", "durum-deposu", "tarife-deposu"],
};
export const YUK = { takip: 8, olay: 2, ucret: 1 };   // tur basina istek, K01 oranina yakin

const HEPSI = [...new Set(Object.values(AKIS).flat())];
export const YERLESIM = {                      // paylasilan olarak isaretlenmemis her sey damga ici
  "tek-parca": HEPSI,
  "paylasilan-damga": ["yonlendirme", "onbellek", "numara-dagitici", "tarife-deposu"],
  "kendine-yeten": ["yonlendirme"],
};
export const BILESENLER = HEPSI;

export const kapsam = (yerlesim, b) => (YERLESIM[yerlesim].includes(b) ? "paylasilan" : "damga");

export function damgaSayisi(yerlesim) {        // tek parca duzeninde damga kavrami yoktur
  return yerlesim === "tek-parca" ? 1 : DAMGA;
}

export function gecenBag(yerlesim) {           // damga siniri kac kez asiliyor
  let n = 0;
  for (const yol of Object.values(AKIS))
    for (let i = 0; i + 1 < yol.length; i += 1)
      if (kapsam(yerlesim, yol[i]) !== kapsam(yerlesim, yol[i + 1])) n += 1;
  return n;
}

export function bulasma(yerlesim, dusen) {     // bir bilesen dusunce etkilenen istek ve damga
  const d = damgaSayisi(yerlesim);
  const toplam = Object.values(YUK).reduce((a, b) => a + b, 0) * d;
  let etkilenen = 0;
  for (const [ad, yol] of Object.entries(AKIS)) {
    if (!yol.includes(dusen)) continue;
    etkilenen += kapsam(yerlesim, dusen) === "paylasilan" ? YUK[ad] * d : YUK[ad];
  }
  const damga = kapsam(yerlesim, dusen) === "paylasilan" ? d : 1;
  return { etkilenen, toplam, oran: etkilenen / toplam, damga, d };
}
```

```js
// damga/olc.mjs — uc yerlesimde damgayi gecen bag sayisi ve her bilesenin bulasma kapsami
import { AKIS, YERLESIM, BILESENLER, gecenBag, bulasma, damgaSayisi, kapsam } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
console.log(`${BILESENLER.length} bilesen, ${Object.keys(AKIS).length} akis, ` +
  `damga basina 8 takip + 2 olay + 1 ucret istegi.`);
console.log();
console.log("yerlesim          | damga | paylasilan bilesen | damga ici | damgayi gecen bag");
console.log("------------------|-------|--------------------|-----------|------------------");
for (const y of Object.keys(YERLESIM)) {
  const p = BILESENLER.filter((b) => kapsam(y, b) === "paylasilan").length;
  console.log(`${y.padEnd(17)} | ${s(damgaSayisi(y), 5)} | ${s(p, 18)} | ` +
    `${s(BILESENLER.length - p, 9)} | ${s(gecenBag(y), 17)}`);
}

console.log();
console.log("dusen bilesen    |       tek-parca | paylasilan-damga |   kendine-yeten");
console.log("-----------------|-----------------|------------------|----------------");
for (const b of BILESENLER) {
  const hucre = Object.keys(YERLESIM).map((y) => {
    const r = bulasma(y, b);
    return `%${(100 * r.oran).toFixed(1)} (${r.damga}/${r.d})`;
  });
  console.log(`${b.padEnd(16)} | ${s(hucre[0], 15)} | ${s(hucre[1], 16)} | ${s(hucre[2], 14)}`);
}
```

```
9 bilesen, 3 akis, damga basina 8 takip + 2 olay + 1 ucret istegi.

yerlesim          | damga | paylasilan bilesen | damga ici | damgayi gecen bag
------------------|-------|--------------------|-----------|------------------
tek-parca         |     1 |                  9 |         0 |                 0
paylasilan-damga  |     4 |                  4 |         5 |                 6
kendine-yeten     |     4 |                  1 |         8 |                 2

dusen bilesen    |       tek-parca | paylasilan-damga |   kendine-yeten
-----------------|-----------------|------------------|----------------
yonlendirme      |     %90.9 (1/1) |      %90.9 (4/4) |    %90.9 (4/4)
uc               |     %90.9 (1/1) |      %22.7 (1/4) |    %22.7 (1/4)
takip-servisi    |     %72.7 (1/1) |      %18.2 (1/4) |    %18.2 (1/4)
onbellek         |     %72.7 (1/1) |      %72.7 (4/4) |    %18.2 (1/4)
durum-deposu     |    %100.0 (1/1) |      %25.0 (1/4) |    %25.0 (1/4)
olay-kuyrugu     |     %18.2 (1/1) |       %4.5 (1/4) |     %4.5 (1/4)
numara-dagitici  |     %18.2 (1/1) |      %18.2 (4/4) |     %4.5 (1/4)
ucret-isi        |      %9.1 (1/1) |       %2.3 (1/4) |     %2.3 (1/4)
tarife-deposu    |      %9.1 (1/1) |       %9.1 (4/4) |     %2.3 (1/4)
```

#### Bulaşma Kapsamı Neyin Sonucudur

Birinci tablo damgalamanın kâğıt üzerindeki ölçüsünü veriyor. Tek parça düzende damga sınırı yok,
dolayısıyla geçen bağ da yok — ama bağımsız birim de yok. Dört damga açıldığında paylaşılan bileşen
sayısı dörde inip geçen bağ 6 oluyor; paylaşılanlar damgaya taşındığında geçen bağ 2'ye iniyor.
**Damga sayısı bağımsızlığı vermez; paylaşılan bileşen sayısı verir.**

İkinci tablo bunun karşılığını her bileşen için ayrı ayrı sayıyor. Damga içi bileşenlerde kapsam
dörde bölünüyor: uç bileşeninin kaybı yüzde 90,9'dan yüzde 22,7'ye, durum deposunun kaybı yüzde
100'den yüzde 25'e iniyor ve etkilenen damga 4'ten 1'e düşüyor. Kalıbın vaadi bu sütundur.

Paylaşılan bileşenlerde ise damgalama hiçbir şey yapmıyor. Önbellek ortada kaldığında kaybı
tek parça düzenle aynı: yüzde 72,7 ve 4/4 damga. Damgaya taşındığında yüzde 18,2 ve 1/4 oluyor.
Aynı desen numara dağıtıcı (yüzde 18,2 → yüzde 4,5) ve tarife deposu (yüzde 9,1 → yüzde 2,3) için
de geçerli. **Bir bileşen damga dışında kaldığı sürece damga sayısını artırmak onun bulaşma
kapsamını değiştirmez.**

Yönlendirme eşlemesi satırı üç sütunda da aynı: yüzde 90,9 ve 4/4. Bu, hangi gönderinin hangi
damgada olduğunu bilen tek kaynaktır ve damgaya taşınamaz — taşınırsa isteğin hangi damgaya
gideceği bilinemez. Kalıbın sınırı budur: **damgalama bulaşma kapsamını sıfırlamaz, onu paylaşılan
kalan tek noktaya indirger.** O noktanın hizmet erişilebilirliği bütün sistemin üst sınırıdır ve
K01'in en zayıf halka kuralı burada birebir geçerlidir.

#### Damga Sayısı Neyi Değiştirir

```js
// damga/yuk.mjs — damga sayisinin K01 yuklerine ve arizasiz gunun bedeline cevrilmesi
const TEPE_UC = 513.89;       // K01: tepe uctaki istek/s
const TEPE_YAZMA = 97.22;     // K01: tepe yazma istek/s
const DEPO = 138.89;          // K01: depoya ulasan istek/s
const GONDERI = 400_000;      // K01: gunluk gonderi
const DAMGA_ICI = 8;          // modelden: kendine-yeten yerlesimde damga ici bilesen sayisi
const b = (x, n = 2) => x.toFixed(n);

console.log(`${"damga".padStart(6)}${"damga basina uc".padStart(17)}${"damga basina depo".padStart(19)}` +
  `${"damga basina yazma".padStart(20)}${"bulasma kapsami".padStart(17)}${"gunluk gonderi".padStart(16)}`);
for (const n of [1, 2, 4, 8, 16]) {
  console.log(`${String(n).padStart(6)}${b(TEPE_UC / n).padStart(17)}${b(DEPO / n).padStart(19)}` +
    `${b(TEPE_YAZMA / n).padStart(20)}${("%" + b(100 / n)).padStart(17)}` +
    `${(GONDERI / n).toLocaleString("tr-TR").padStart(16)}`);
}

console.log(`\n${"damga".padStart(6)}${"toplam bilesen".padStart(16)}${"cografi kopyayla".padStart(18)}` +
  `${"ucret isinin dokundugu damga".padStart(30)}`);
for (const n of [1, 2, 4, 8, 16]) {
  const bilesen = DAMGA_ICI * n + 1;        // +1: paylasilan yonlendirme eslemesi
  console.log(`${String(n).padStart(6)}${String(bilesen).padStart(16)}` +
    `${String(DAMGA_ICI * n * 2 + 1).padStart(18)}${String(n).padStart(30)}`);
}
console.log(`paylasilan tek kaynagin bulasma kapsami damga sayisindan bagimsizdir: her zaman %90,9`);
```

```
 damga  damga basina uc  damga basina depo  damga basina yazma  bulasma kapsami  gunluk gonderi
     1           513.89             138.89               97.22          %100.00         400.000
     2           256.94              69.44               48.61           %50.00         200.000
     4           128.47              34.72               24.30           %25.00         100.000
     8            64.24              17.36               12.15           %12.50          50.000
    16            32.12               8.68                6.08            %6.25          25.000

 damga  toplam bilesen  cografi kopyayla  ucret isinin dokundugu damga
     1               9                17                             1
     2              17                33                             2
     4              33                65                             4
     8              65               129                             8
    16             129               257                            16
paylasilan tek kaynagin bulasma kapsami damga sayisindan bagimsizdir: her zaman %90,9
```

Birinci tablo damgalamanın ölçekleme yüzüdür: dört damgada damga başına uç yükü 128,47 istek/s,
depoya ulaşan 34,72 istek/s ve günlük 100.000 gönderi. K01'in bütün hesapları damga başına yeniden
okunabilir hâle geliyor ve bir damganın kapasitesi bilindiğinde kaç damga gerektiği bölmeyle
bulunuyor. Bulaşma kapsamı sütunu aynı bölmenin dayanıklılık yüzüdür ve ikisi aynı sayıdır — ölçek
birimi ile arıza yalıtım birimi burada çakışır.

İkinci tablo **arızasız günün bedelini** veriyor. Toplam bileşen sayısı damga sayısıyla doğrusal
büyüyor: bir damgada 9, on altı damgada 129. Her damganın ikinci bir bölgede **coğrafi kopyası**
tutulursa sayı ikiye katlanıyor: 257. Coğrafi kopya, damganın bütününün başka bir bölgede
çoğaltılmasıdır; çoğaltmanın mekaniği Veri Katmanı Ölçekleme kursunda kuruldu ve burada
tekrarlanmaz, buradaki yenilik çoğaltılan şeyin bir kayıt değil bir **dağıtım birimi** olmasıdır.

Son sütun damgalamanın en görünmeyen bedelidir. Gün sonu ücretlendirmesi bütün gönderilere
dokunmak zorundadır ve gönderiler damgalara bölünmüştür; iş on altı damgada on altı yere gitmek ve
sonuçlarını birleştirmek zorunda kalır. Damga başına düşen istek azalırken, damgayı **geçmek
zorunda olan** iş için dağılım bir maliyettir. Bu iş K01'in dört saatlik penceresine bağlıdır ve
pencere değişmiyor; değişen, işin kaç parçadan toplandığıdır.

#### İki Günün Sayısı

**Arızasız günün bedeli** üç kalemdir. Bileşen sayısı 9'dan 33'e (dört damga), coğrafi kopyayla
65'e çıkıyor — her biri ayrı kurulan, ayrı yükseltilen ve ayrı izlenen birer birim. Gün sonu
ücretlendirmesi tek yerine dört yere gidiyor. Ve iki damgayı birden ilgilendiren bir sorgu, damga
sınırını geçtiği için tasarımda yeri olmayan bir işlem hâline geliyor; kendine yeten yerleşimde
sınırı geçen yalnız 2 bağ kalmıştı ve o iki bağ da yönlendirme eşlemesine gidiyordu.

**Arızalı günün kazancı** ikinci tablonun damga içi satırlarındadır. Aynı arıza — durum deposunun
kaybı — tek parça düzende isteklerin yüzde 100'ünü, dört damgalı düzende yüzde 25'ini, on altı
damgalı düzende yüzde 6,25'ini etkiliyor. Uç bileşeninin kaybı yüzde 90,9'dan yüzde 22,7'ye
iniyor. Bir arızanın süresi değişmiyor; değişen, o süre boyunca kaç kullanıcının etkilendiğidir ve
K01'in istek tabanlı erişilebilirlik ölçümü tam olarak bunu sayar.

İki günün karşılaştırması bir sınır da veriyor. Damga sayısını artırmak bulaşma kapsamını $1/n$ ile
küçültürken bileşen sayısını $n$ ile büyütüyor. Paylaşılan tek kaynağın kapsamı ise yüzde 90,9'da
duruyor ve hiç küçülmüyor; kalıbın kazancı bu tabanın üstünde kalan payla sınırlıdır.

#### Özet

- Dağıtım damgası hizmetin kendi kendine yeten ve yinelenebilir bir kopyasıdır; ölçekleme birimi
  olarak kullanıldığında ölçek birimi adını alır ve sürüm damgasından ayrı bir kavramdır.
- Bağımsızlığın ölçüsü damga sayısı değil, damgayı geçen bağ sayısıdır: dört damgalı düzende
  paylaşılan bileşenlerle 6, paylaşılanlar damgaya taşındığında 2.
- Damga içi bileşenlerde bulaşma kapsamı dörde bölünüyor (durum deposu yüzde 100'den yüzde 25'e),
  paylaşılan bileşenlerde hiç değişmiyor (önbellek yüzde 72,7'de, 4/4 damgada kalıyor).
- Yönlendirme eşlemesi damgaya taşınamaz ve kapsamı üç yerleşimde de yüzde 90,9'dur: damgalama
  bulaşma kapsamını sıfırlamaz, paylaşılan kalan tek noktaya indirger.
- Damga sayısı K01 yüklerini doğrudan böler: dört damgada damga başına 128,47 istek/s uç, 34,72
  istek/s depo ve 100.000 günlük gönderi; bulaşma kapsamı aynı bölmedir.
- Arızasız günün bedeli bileşen sayısıdır: 9'dan dört damgada 33'e, coğrafi kopyayla 65'e; ayrıca
  gün sonu ücretlendirmesi damga sayısı kadar yere gitmek zorunda kalır.

#### Sonraki Adım

Bu konu beş derste bir kurtarma düzeni kurdu: devralma eşiği ve geri dönüş politikası, sağlık
ucunun içeriği ve aralığı, kurtarma süresi ile veri kaybı hedefleri, alan ve bölge yerleşimi,
damgalar ve coğrafi kopyalar. Hepsinin sayıları bir modelden ya da aritmetikten çıktı ve hepsi bir
şeyi varsaydı: **plan yazıldığı gibi çalışacak.** Devralma eşiği doğru tetikleyecek, yedek kopya
gerçekten güncel olacak, ikinci bölge yükü kaldıracak, damgadaki her bileşen gerçekten damganın
içinde olacak. Bu varsayımların hiçbiri sınanmadı. Sonraki ders planı denetimli bir arıza
denemesiyle sınar: tatbikatın kendisi kesinti bütçesinden ne kadar yer tutuyor, hedeflenen kurtarma
süresi ile tatbikatta ölçülen arasındaki fark nedir ve tatbikatsız bir düzende ilk gerçek arıza
hangi varsayımları birden kırar.

### Felaket Kurtarma Tatbikatı

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/felaket-kurtarma-tatbikati

Kurtarma planının denetimli bir arıza denemesiyle sınanması: plandaki adım sürelerinin tatbikatta ölçülenle karşılaştırılması, planda hiç yazmayan adımın ortaya çıkması, kurtarma süresi hedefinin plana göre tutup tatbikata göre kırılması ve devralma penceresinde yarıda kalan iş akışlarının iki teslim politikasında bıraktığı yinelenen yan etki ile yarım kalan işin sayılması.

Bu konu beş derste bir kurtarma düzeni kurdu: devralma eşiği ve geri dönüş politikası, sağlık
ucunun içeriği ve aralığı, kurtarma süresi ile veri kaybı hedefleri, alan ve bölge yerleşimi,
damgalar ve coğrafi kopyalar. Her dersin sayıları bir modelden ya da aritmetikten çıktı ve hepsi
aynı şeyi varsaydı: **plan yazıldığı gibi çalışacak.**

Bu varsayım sınanmadıkça bir tahmindir. **Felaket kurtarma tatbikatı**, planı denetimli bir arıza
denemesiyle sınamaktır: belirli bir birim, seçilmiş bir zamanda, bilinerek devre dışı bırakılır ve
kurtarmanın gerçekte nasıl işlediği ölçülür. Bir tatbikatın kapsamı üç şeyle tanımlanır — hangi
birim (kopya, alan, bölge, damga), hangi arıza kipi (durma, yavaşlama, bölünme) ve ne kadar süre.
Kapsam yazılmadan yapılan bir deneme, ölçtüğü şeyi de söyleyemez.

#### Plan ile Ölçülenin Farkı

Bir kurtarma planı adımların listesidir ve her adıma bir süre biçilmiştir. Tatbikatın birinci
çıktısı bu sürelerin karşılaştırmasıdır. Aşağıdaki hesapta ölçülen değerler uydurulmadı: önceki
derslerin parametrelerinden geliyor. Algılama süresi birinci dersin seçtiği eşiktir, ısınma süresi
ikinci dersin arıza takvimindeki ısınma penceresidir.

**KU8 — yönlendirme kaydının yaşam süresi 3 tur.** Gerekçe: yeni etkin kopyaya yönlendirme,
eskisinin kaydı geçersiz olana kadar tamamlanmaz. **KU9 — kuyruk tüketicisinin yeniden bağlanması
2 tur.** İkisi de varsayımdır ve K01'in tablosuna eklenmez.

```js
// tatbikat/plan.mjs — kurtarma planindaki adim sureleri ile tatbikatta olculenin karsilastirilmasi.
// Olculen degerler onceki derslerin parametrelerinden gelir; tur soyut bir adimdir.
const ESIK = 3;          // 01. ders: secilen tetikleme esigi
const TERFI = 1;         // 01. ders: terfi turu
const YASAM = 3;         // KU8 (varsayim): yonlendirme kaydinin yasam suresi (tur)
const ISINMA = 8;        // 02. ders takvimi: bir kopyanin isinma suresi (tur)
const KUYRUK = 2;        // KU9 (varsayim): kuyruk tuketicisinin yeniden baglanmasi (tur)
const DOGRULAMA = 2;     // planda yazili dogrulama adimi
const TUR_SN = 2;        // KU1 (varsayim): bir tur 2 saniye
const TEPE_UC = 513.89;  // K01: tepe uctaki istek/s
const PLANLI = 15.0;     // K01: aylik butcenin planli isler payi (dakika)
const b = (x, n = 2) => x.toFixed(n);

const ADIM = [
  ["algilama", 1, ESIK], ["terfi", 1, TERFI], ["yonlendirme", 1, YASAM],
  ["onbellek-isinma", 0, ISINMA], ["kuyruk-baglanma", 1, KUYRUK], ["dogrulama", 2, DOGRULAMA],
];
console.log(`${"adim".padEnd(17)}${"planlanan".padStart(11)}${"tatbikatta".padStart(12)}${"sapma".padStart(8)}`);
let p = 0, o = 0;
for (const [ad, plan, olculen] of ADIM) {
  p += plan; o += olculen;
  const d = olculen - plan;
  console.log(`${ad.padEnd(17)}${(plan + " tur").padStart(11)}${(olculen + " tur").padStart(12)}` +
    `${((d >= 0 ? "+" : "") + d).padStart(8)}`);
}
console.log(`${"toplam".padEnd(17)}${(p + " tur").padStart(11)}${(o + " tur").padStart(12)}` +
  `${("+" + (o - p)).padStart(8)}`);
console.log(`plan/olculen orani ${b(o / p)} kat`);

console.log(`\nplan ${p * TUR_SN} sn, tatbikatta olculen ${o * TUR_SN} sn (KU1: tur = ${TUR_SN} sn)`);
for (const hedef of [30, 60]) {
  const pl = p * TUR_SN <= hedef ? "gecer" : "kirilir", ol = o * TUR_SN <= hedef ? "gecer" : "kirilir";
  console.log(`  kurtarma suresi hedefi ${hedef} sn: plana gore ${pl}, tatbikata gore ${ol}`);
}
console.log(`  tatbikat penceresinde dusen uc istegi = ${b(o * TUR_SN * TEPE_UC)} (tepe yukte)`);
console.log(`\ntatbikatin kendi bedeli (bir tatbikat = ${b((o * TUR_SN) / 60)} dk):`);
console.log(`${"siklik".padEnd(14)}${"aylik tatbikat".padStart(16)}${"aylik dakika".padStart(14)}` +
  `${"planli payin".padStart(14)}${"aylik butcenin".padStart(16)}`);
for (const [ad, ayda] of [["haftada 1", 4], ["ayda 1", 1], ["uc ayda 1", 1 / 3]]) {
  const dk = (ayda * o * TUR_SN) / 60;
  console.log(`${ad.padEnd(14)}${b(ayda).padStart(16)}${b(dk).padStart(14)}` +
    `${("%" + b((100 * dk) / PLANLI)).padStart(14)}${("%" + b((100 * dk) / 43.2)).padStart(16)}`);
}
console.log(`plandaki 6 adimin ${ADIM.filter(([, pl, ol]) => ol !== pl).length}'i saptigi olculdu; ` +
  `biri (onbellek-isinma) planda hic yoktu`);
```

```
adim               planlanan  tatbikatta   sapma
algilama               1 tur       3 tur      +2
terfi                  1 tur       1 tur      +0
yonlendirme            1 tur       3 tur      +2
onbellek-isinma        0 tur       8 tur      +8
kuyruk-baglanma        1 tur       2 tur      +1
dogrulama              2 tur       2 tur      +0
toplam                 6 tur      19 tur     +13
plan/olculen orani 3.17 kat

plan 12 sn, tatbikatta olculen 38 sn (KU1: tur = 2 sn)
  kurtarma suresi hedefi 30 sn: plana gore gecer, tatbikata gore kirilir
  kurtarma suresi hedefi 60 sn: plana gore gecer, tatbikata gore gecer
  tatbikat penceresinde dusen uc istegi = 19527.82 (tepe yukte)

tatbikatin kendi bedeli (bir tatbikat = 0.63 dk):
siklik          aylik tatbikat  aylik dakika  planli payin  aylik butcenin
haftada 1                 4.00          2.53        %16.89           %5.86
ayda 1                    1.00          0.63         %4.22           %1.47
uc ayda 1                 0.33          0.21         %1.41           %0.49
plandaki 6 adimin 4'i saptigi olculdu; biri (onbellek-isinma) planda hic yoktu
```

Toplam satırı dersin ilk sonucudur: plan 6 tur diyordu, tatbikat 19 tur ölçtü — 3,17 kat. Bu oran
koşumdan bağımsız türetilmiş bir niceliktir; tur saniyeye çevrilmese de aynı kalır.

Sapma tek bir yerden gelmiyor. Algılama ve yönlendirme adımları planda birer tur yazılmış, oysa
birincisi seçilen eşiğe, ikincisi yönlendirme kaydının yaşam süresine bağlıdır — ikisi de başka
derslerde **verilmiş** kararlardır ve plan onları okumamıştır. En büyük sapma ise planda hiç
olmayan bir adımdan geliyor: önbelleğin ısınması. Yeni etkin kopya ayaktadır, yazma kabul eder ve
sağlık denetimini geçer, ama okumaları soğuk önbellekle karşılar. **Planın en pahalı hatası yanlış
tahmin değil, eksik adımdır.**

Sonuç eşiğe çarpıyor. Otuz saniyelik bir kurtarma süresi hedefi plana bakıldığında rahatça
tutuluyor (12 saniye), tatbikata bakıldığında kırılıyor (38 saniye). Altmış saniyelik hedef her iki
okumada da geçiyor. Bir hedefin tutulup tutulmadığı plandan okunamaz; tatbikat, hedefi bir iddia
olmaktan çıkarıp ölçülmüş bir sayıya bağlayan tek adımdır.

#### Kapsam ve Sıklık

Tatbikatın kapsamı bir merdivendir ve her basamak farklı bir şey sınar. En alt basamak plan
adımlarının kâğıt üzerinde gözden geçirilmesidir; bu, eksik adımı bulabilir ama süreyi ölçemez —
yukarıdaki tabloda önbellek ısınmasının planda hiç olmaması bu yolla yakalanabilirdi, sekiz turluk
süresi yakalanamazdı. Orta basamak tek bir bileşenin devre dışı bırakılmasıdır; devralma eşiğini ve
sağlık ucunun içeriğini sınar. Üst basamak bir alanın ya da bölgenin bütününün kaybıdır ve önceki
iki dersin yerleşim kararlarını sınayan tek denemedir; yalnız burada boşta duran kapasitenin gerçek
yükü taşıyıp taşımadığı görülür.

Sıklık tablosu bedeli sıklığa bağlıyor. Haftada bir tatbikat ayda 2,53 dakika tutar — planlı işler
payının yüzde 16,89'u ve aylık bütçenin yüzde 5,86'sı. Ayda bir tatbikat 0,63 dakika, üç ayda bir
0,21 dakika. Seyrek tatbikat ucuzdur ama iki tatbikat arasında biriken değişiklikler planı yeniden
eskitir; ölçülen sapma her seferinde sıfırdan büyür. Bu ders sayıyı verir, seçimi vermez: seçim
plandaki adımların ne sıklıkla değiştiğine bağlıdır.

#### Tatbikatın Ortaya Çıkardığı İkinci Sorun

Tatbikatın son adımı doğrulamadır: kurtarma bittikten sonra verinin ve devam eden işlerin durumuna
bakmak. Kurtarma süresi ölçüldü, ama devralma penceresinde **yarıda kalan işlere** ne olduğu
sayılmadı. Aşağıdaki düzenek bir **modeldir**: gün sonu ücretlendirme akışı sekiz adımdır, dördü
yan etkilidir (fatura yazmak, muhasebe kaydı açmak, bildirim göndermek, taşıyıcıya haber vermek) ve
devralma penceresi az önce ölçülen 19 turdur.

```js
// tatbikat/is.mjs — tatbikatin veri dogrulama adimi MODELIDIR: devralma penceresinde yarida
// kalan is akislarinin iki politikada ne biraktigi sayilir. Tur soyut bir adimdir.
const ADIM = [                                  // ucretlendirme is akisinin adimlari
  ["durum-oku", false], ["tarife-uygula", false], ["tutar-hesapla", false],
  ["fatura-yaz", true], ["muhasebe-kaydi", true], ["bildirim-gonder", true],
  ["tasiyici-bildir", true], ["kapat", false],
];
const TUR = 70, IS_TUR = 4, BASLANGIC_SON = 40;  // her turda 4 is baslar, 40. tura kadar
const DEVRALMA = 20, PENCERE = 19;               // 19 tur: plan.mjs'te olculen toplam

function kosum(politika) {
  const isler = [];
  const s = { tamamlanan: 0, yinelenenYanEtki: 0, yarimKalan: 0, yenidenBaslayan: 0, atilan: 0 };
  for (let t = 1; t <= TUR; t += 1) {
    const donuk = t >= DEVRALMA && t < DEVRALMA + PENCERE;
    if (t === DEVRALMA) {
      for (const w of isler) {
        if (w.adim === 0 || w.adim >= ADIM.length) continue;   // baslamamis ya da bitmis
        if (politika === "en-az-bir-kez") {
          s.yenidenBaslayan += 1;
          s.yinelenenYanEtki += ADIM.slice(0, w.adim).filter(([, y]) => y).length;
          w.adim = 0;                                          // is bastan calisacak
        } else {
          s.atilan += 1;
          if (ADIM.slice(0, w.adim).some(([, y]) => y)) s.yarimKalan += 1;
          w.olu = true;
        }
      }
    }
    if (donuk) continue;                                       // pencere boyunca is ilerlemiyor
    for (const w of isler) {
      if (w.olu || w.adim >= ADIM.length) continue;
      w.adim += 1;
      if (w.adim === ADIM.length) s.tamamlanan += 1;
    }
    if (t <= BASLANGIC_SON) for (let i = 0; i < IS_TUR; i += 1) isler.push({ adim: 0, olu: false });
  }
  return { ...s, toplam: isler.length };
}

const s = (x, n) => String(x).padStart(n);
console.log(`${TUR} tur, turda ${IS_TUR} is akisi baslar, her akis ${ADIM.length} adim ` +
  `(${ADIM.filter(([, y]) => y).length} tanesi yan etkili). Devralma ${DEVRALMA}. turda, ` +
  `pencere ${PENCERE} tur.`);
console.log();
console.log("politika       | toplam is | tamamlanan | yeniden baslayan | atilan | yinelenen yan etki | yarim kalan");
console.log("---------------|-----------|------------|------------------|--------|--------------------|------------");
for (const p of ["en-az-bir-kez", "en-cok-bir-kez"]) {
  const r = kosum(p);
  console.log(`${p.padEnd(14)} | ${s(r.toplam, 9)} | ${s(r.tamamlanan, 10)} | ` +
    `${s(r.yenidenBaslayan, 16)} | ${s(r.atilan, 6)} | ${s(r.yinelenenYanEtki, 18)} | ${s(r.yarimKalan, 11)}`);
}
```

```
70 tur, turda 4 is akisi baslar, her akis 8 adim (4 tanesi yan etkili). Devralma 20. turda, pencere 19 tur.

politika       | toplam is | tamamlanan | yeniden baslayan | atilan | yinelenen yan etki | yarim kalan
---------------|-----------|------------|------------------|--------|--------------------|------------
en-az-bir-kez  |        84 |         84 |               28 |      0 |                 40 |           0
en-cok-bir-kez |        84 |         56 |                0 |     28 |                  0 |          16
```

İki satır iki kötü sonucu gösteriyor ve arada üçüncü bir seçenek yok. **En az bir kez** teslimde
işlerin hepsi tamamlanıyor: 84/84. Karşılığında devralma anında yarıda olan 28 iş baştan çalışıyor
ve daha önce yürütülmüş yan etkili adımlar **ikinci kez** yürütülüyor — 40 yinelenen yan etki. Bu,
40 fazladan fatura satırı, muhasebe kaydı ya da taşıyıcı bildirimi demektir.

**En çok bir kez** teslimde yineleme yok, ama tamamlanan iş 84'ten 56'ya iniyor: 28 iş atılıyor ve
bunların 16'sı en az bir yan etkili adımı yürütmüş durumda. Yani 16 gönderi için fatura yazılmış ama
muhasebe kaydı açılmamış, ya da bildirim gönderilmiş ama iş kapanmamıştır. Bu işler ne tamamlandı
ne de geri alındı; sistemde iz bıraktılar ve kimse onları toplamıyor.

Kurtarma penceresinin uzunluğu bu sayıları doğrudan büyütüyor. Pencere 19 tur olduğu için 28 iş
yarıda kaldı; plandaki 6 turluk pencerede bu sayı daha küçük olurdu. **Kurtarma süresini kısaltmak
yalnız kesinti bütçesini korumaz, doğruluk hasarını da küçültür** — iki dersin ölçtüğü iki ayrı
büyüklük aynı yerde buluşuyor.

#### İki Günün Sayısı

**Arızasız günün bedeli** tatbikatın kendisidir. Ayda bir yapılan tatbikat 38 saniye, yani 0,63 dakika
tutar ve K01'in planlı işlere ayırdığı 15,0 dakikanın yüzde 4,22'sini harcar. Tepe yükte yapılırsa
19.527,82 uç isteği düşer; bu yüzden tatbikat kapsamı zaman penceresini de içerir. Bedel gerçektir
ve gönüllü ödenir.

**Arızalı günün kazancı** iki tabloyu birlikte okumakla çıkar. Tatbikatsız bir düzende plan 12
saniyelik bir kurtarma süresi vaat ediyordu; gerçek arızada ölçülen 38 saniye olacaktı ve 30
saniyelik hedef ilk arızada kırılacaktı. Tatbikat bu farkı, hedefi kırmadan önce görünür kıldı.
Ayrıca planda hiç olmayan bir adımı ortaya çıkardı ve altı adımın dördünün süresinin yanlış
yazıldığını ölçtü. Aynı tatbikat, kurtarma süresiyle hiç ilgisi olmayan bir hasarı da saydı: 40
yinelenen yan etki ya da 16 yarım kalan iş.

Bu karşılaştırma bu kursun kuralının en açık örneğidir. Tatbikat arızasız günde yalnız bedel öder —
0,63 dakika ve 19.527,82 istek. Kazancı yalnız arıza gerçekleştiğinde görünür ve o gün, bilinmeyen
bir sapmayla karşılaşmamak biçiminde ortaya çıkar.

#### Özet

- Tatbikat, kurtarma planını denetimli bir arıza denemesiyle sınamaktır; kapsamı hangi birim, hangi
  arıza kipi ve ne kadar süre sorularıyla tanımlanır.
- Planda 6 tur yazan kurtarma tatbikatta 19 tur ölçüldü (3,17 kat); altı adımın dördünün süresi
  yanlış yazılmıştı ve en büyük sapma planda hiç olmayan önbellek ısınmasından geldi.
- Hedef plandan sınanamaz: 30 saniyelik kurtarma süresi hedefi plana göre geçiyor, tatbikatta
  ölçülen 38 saniyeye göre kırılıyor.
- Tatbikatın bedeli sıklığa bağlıdır: ayda bir tatbikat 0,63 dakika (planlı payın yüzde 4,22'si),
  haftada bir 2,53 dakika (yüzde 16,89); tepe yükte her tatbikat 19.527,82 uç isteği düşürür.
- Doğrulama adımı ikinci bir hasarı ortaya çıkardı: 19 turluk pencerede 28 iş akışı yarıda kaldı;
  en az bir kez teslimde hepsi tamamlandı ama 40 yan etki ikinci kez yürüdü, en çok bir kez
  teslimde yineleme olmadı ama 16 iş yarım kaldı.
- Kurtarma penceresini kısaltmak yalnız kesinti bütçesini korumaz; yarıda kalan iş sayısını da
  küçülterek doğruluk hasarını azaltır.

#### Sonraki Adım

Tatbikat kurtarma düzenini doğruladı ve aynı zamanda onun sınırını gösterdi. Devralma tamamlandı,
hedefler ölçüldü, yerleşim sınandı — ama son tablo bu konunun hiçbir kalıbıyla çözülemeyen bir şey
bıraktı. **Aynı iş iki kez çalıştı:** 40 yan etkili adım yeniden yürüdü, çünkü yeni etkin kopya
işin nerede kaldığını bilmiyordu ve baştan başlattı. Aynı sorun yalnız devralmada değil, önceki
konudaki yeniden denemede de doğar; her yeniden gönderilen istek daha önce işlenmiş olabilir.
Öteki uçta **yarım kalan iş akışları geri alınmadı:** 16 iş bir yan etki bırakıp durdu ve onları
toplayacak bir adım tasarlanmadı. Sonraki konu bu iki soruyu ele alır: bir isteğin ikinci kez
işlenmesinin zararsız kılınması ve geri alınamayan adımların dengelenmesi.

## Dağıtık Doğruluk

Arıza altında yeniden denenen, yarıda kalan ve aşamalı olarak taşınan işlerin doğru sonuç vermesi: yinelenen isteğin yan etki üretmeden zararsızlaştırılması, geri alınamayan adımların telafi edici işlemlerle dengelenmesi, büyük yükün ileti dışında taşınması, doğrudan kaynak erişimi için sınırlı süreli yetki verilmesi, çalışma zamanı ayarlarının dışarıda toplanması ve eski sistemin yol yol değiştirilmesi.

### Etkisiz İşlemler

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/etkisiz-islemler

Kurtarma sırasında yinelenen isteğin zararsızlaştırılması: yinelemenin üç kaynağının doksan saniyelik bir arıza penceresinde sayılması, tekillik anahtarının kapsamının yanlış seçildiğinde geçerli olayı bastırması ve anahtar defterinin K01 ölçeğinde tuttuğu kayıt, kapladığı bayt ile ikiye katladığı yazma satırı.

Kurtarma ve Süreklilik konusu tatbikatla kapandı ve iki açık kalan sorun bıraktı. Devralma ile
yeniden deneme birlikte çalıştığında **aynı iş iki kez** yürüdü: bir taşıyıcı bildirimi hem
zaman aşımı sonrası yeniden gönderildi hem de devralan kopya tarafından kütükten yeniden
sürüldü. İkincisi, yarıda kesilen iş akışları geri alınmadı. Bu ders birincisini ele alır.

**Etkisizlik** ve **tekillik anahtarı** (idempotency key) API Tasarımı ile Veri Erişim Katmanı
kurslarında tanımlandı; aynı anahtarla gelen ikinci isteğin ilk yanıtı sunması, anahtarın etkiyle
aynı işlemde saklanması ve teslim semantiğinin etkiyi değil teslimi çoğalttığı orada gösterildi.
Burada tanım tekrarlanmaz. Bu dersin iki sorusu vardır: bir arıza penceresinde yinelemenin
**kaç yan etki** ürettiği ve o yinelemeyi tutan defterin **arızasız günde neye mal olduğu**.

#### Yinelemenin Üç Kaynağı

Arıza senaryosu adıyla tanımlanır. **Taşıyıcı bildirim ucu yavaşlıyor**: uç yanıt vermeyi
sürdürüyor ama yanıt süresi çağıranın zaman aşımı eşiğini geçiyor, dolayısıyla çağıran isteği
başarısız sayıp yeniden deniyor. Yavaşlama sırasında bir kopya devralınırsa devralan taraf
kütükteki son yazmaları yeniden sürer, kuyruk tarafı da onaylanmamış iletiyi yeniden teslim eder.
Üç kaynak aynı anda çalışır.

**DD1 — arıza penceresi 90 saniye, ayda 2 kez.** Gerekçesi: bu süre K01'in 10 dakikalık
kurtarma süresi varsayımının altındadır ve aylık kesinti bütçesinde kesinti olarak görünmez, ama
zaman aşımı eşiğinin üstündedir. Duyarlılığı ayda 4 pencere ile verilir. **DD2 — pencerede bir
yazmanın yinelenme olasılığı 0,35**, üç kaynağa bölünür: taşıyıcının yeniden denemesi 0,20,
devralmada yeniden sürme 0,10, en az bir kez yeniden teslim 0,05. İkisi de varsayımdır ve K01'in
tablosuna eklenmez.

Düzenek süreç içi bir modeldir: kuyruk, depo ve ağ yoktur, defter bir kümedir ve yan etkiler
birer sayaçtır. Modelin taşıdığı tek özellik, aynı olayın birden çok kez işleyiciye ulaşmasıdır.

```js
// etkisiz/akis.mjs — durum olayi akisinin ve tekillik defterinin surec ici modeli.
// Gercek kuyruk, depo ya da ag yoktur: defter bir kume, yan etkiler birer sayactir.

export const DIZI = ["kabul", "aktarma", "aktarma", "aktarma",
  "dagitima-cikis", "teslim-denemesi", "teslim"];        // K01 V4 = gonderi basina 7 durum olayi

export function uretec(tohum) {              // 32 bitlik dogrusal esitlikli uretec, tohum acik
  let s = tohum >>> 0;
  return () => { s = (Math.imul(s, 1103515245) + 12345) >>> 0; return s / 4294967296; };
}

export const olaylar = (gonderi) =>
  DIZI.map((durum, i) => ({ takip: `TR-${gonderi}`, durum, olayNo: i }));

export const anahtar = (o, kip) => kip === "takip" ? o.takip
  : kip === "takip+durum" ? `${o.takip}|${o.durum}` : `${o.takip}|${o.durum}|${o.olayNo}`;

// Yan etki: her olay bir durum kaydi yazar; teslim ayrica ucret kalemi ekler ve bildirim yollar.
export const yanEtki = (o) => (o.durum === "teslim" ? 3 : 1);

export function isleyici({ defterli, kip }) {
  const defter = new Set();
  const s = { islenen: 0, bastirilan: 0, yanEtki: 0 };
  return {
    s,
    al(o) {
      const a = anahtar(o, kip);
      if (defterli && defter.has(a)) { s.bastirilan += 1; return; }
      defter.add(a);
      s.islenen += 1;
      s.yanEtki += yanEtki(o);
    },
    boy: () => defter.size,
  };
}

// Teslim akisi: her olay bir kez gelir; ariza penceresinde uc kaynak fazladan teslim uretir.
export function teslimler(gonderiSayisi, kaynaklar, tohum) {
  const rnd = uretec(tohum);
  const akis = [], sayac = new Map(kaynaklar.map(([ad]) => [ad, 0]));
  for (let g = 0; g < gonderiSayisi; g += 1)
    for (const o of olaylar(g)) {
      akis.push(o);
      for (const [ad, p] of kaynaklar)
        if (rnd() < p) { akis.push(o); sayac.set(ad, sayac.get(ad) + 1); }
    }
  return { akis, sayac };
}
```

Aynı akış üç anahtar kipiyle ve deftersiz olarak koşturulur. Anahtar kipi bir kapsam kararıdır:
anahtar yalnız takip numarasından mı, takip numarası ile durumdan mı, yoksa taşıyıcının ürettiği
olay kimliğini de içeren üçlüden mi oluşur.

```js
// etkisiz/olc.mjs — arizasiz gunun bedeli ile ariza penceresinin kazanci ayri ayri sayilir
import { DIZI, teslimler, isleyici } from "./akis.mjs";

const TEPE_YAZMA = 97.22, PENCERE = 90;                  // K01 hesabi; DD1 ariza penceresi
const GONDERI = Math.round((TEPE_YAZMA * PENCERE) / DIZI.length);
const KAYNAK = [["tasiyicinin yeniden denemesi", 0.20],  // DD2, uc kaynaga bolunmus
  ["devralmada yeniden surme", 0.10], ["en az bir kez yeniden teslim", 0.05]];
const KIP = ["takip", "takip+durum", "takip+durum+olay"];

const kos = (kaynaklar, tohum) => {
  const { akis, sayac } = teslimler(GONDERI, kaynaklar, tohum);
  const satir = KIP.map((kip) => {
    const d = isleyici({ defterli: true, kip });
    for (const o of akis) d.al(o);
    return [kip, d.s, d.boy()];
  });
  const y = isleyici({ defterli: false, kip: "takip+durum+olay" });
  for (const o of akis) y.al(o);
  return { akis, sayac, satir, y: y.s };
};

const yaz = (baslik, r) => {
  console.log(`\n${baslik}: ${r.akis.length} teslim, deftersiz yan etki ${r.y.yanEtki}`);
  for (const [ad, s, boy] of r.satir)
    console.log(`${ad.padEnd(22)}${String(s.islenen).padStart(9)}${String(s.bastirilan).padStart(12)}` +
      `${String(s.yanEtki).padStart(10)}${String(r.y.yanEtki - s.yanEtki).padStart(11)}${String(boy).padStart(11)}`);
};

console.log(`model: ${GONDERI} gonderi x ${DIZI.length} olay = ${GONDERI * DIZI.length} ozgun olay`);
console.log(`(K01 tepe yazma ${TEPE_YAZMA} olay/s x DD1 pencere ${PENCERE} s)`);
console.log(`\n${"anahtar kipi".padEnd(22)}${"islenen".padStart(9)}${"bastirilan".padStart(12)}` +
  `${"yan etki".padStart(10)}${"onlenen".padStart(11)}${"defter".padStart(11)}`);
yaz("arizasiz gun (yineleme yok)", kos([], 20260730));
const r = kos(KAYNAK, 20260730);
yaz("ariza penceresi (DD2)", r);
console.log(`kaynak dagilimi: ${[...r.sayac].map(([a, n]) => `${a} ${n}`).join(", ")}`);
const yinelenen = r.akis.length - GONDERI * DIZI.length;
const yinelenenTeslim = r.akis.filter((o) => o.durum === "teslim").length - GONDERI;
console.log(`yinelenen teslim ${yinelenen}, bunun ${yinelenenTeslim} tanesi "teslim" olayidir; ` +
  `yani ${yinelenenTeslim} yinelenen ucret kalemi ve ${yinelenenTeslim} yinelenen bildirim`);
```

```
model: 1250 gonderi x 7 olay = 8750 ozgun olay
(K01 tepe yazma 97.22 olay/s x DD1 pencere 90 s)

anahtar kipi            islenen  bastirilan  yan etki    onlenen     defter

arizasiz gun (yineleme yok): 8750 teslim, deftersiz yan etki 11250
takip                      1250        7500      1250      10000       1250
takip+durum                6250        2500      8750       2500       6250
takip+durum+olay           8750           0     11250          0       8750

ariza penceresi (DD2): 11849 teslim, deftersiz yan etki 15251
takip                      1250       10599      1250      14001       1250
takip+durum                6250        5599      8750       6501       6250
takip+durum+olay           8750        3099     11250       4001       8750
kaynak dagilimi: tasiyicinin yeniden denemesi 1789, devralmada yeniden surme 876, en az bir kez yeniden teslim 434
yinelenen teslim 3099, bunun 451 tanesi "teslim" olayidir; yani 451 yinelenen ucret kalemi ve 451 yinelenen bildirim
```

Bu sayılar **ölçüm** sınıfındadır: tohumu 20260730 olan bir üreteçle koşan süreç içi modelden
gelirler ve aynı tohumla yeniden üretilirler. Girdileri ise K01'in **hesabı** (tepe yazma 97,22
olay/s) ile bu dersin **varsayımlarıdır** (DD1, DD2).

#### Anahtarın Kapsamı Bir Bastırma Kararıdır

Üstteki blok arızasız günü sayıyor ve tablonun en pahalı satırı orada. Yineleme yokken doğru
kapsam (`takip+durum+olay`) hiçbir şeyi bastırmıyor: 8750 olay işleniyor, 11250 yan etki
üretiliyor. Dar kapsamlı `takip` anahtarı ise **7500 geçerli olayı** bastırıyor, çünkü bir
gönderinin yedi durum olayı aynı takip numarasını taşır; geriye yalnız ilki kalıyor ve yan etki
11250'den 1250'ye düşüyor. Orta kapsam `takip+durum` 2500 olay bastırıyor, çünkü dizideki üç
`aktarma` olayı aynı anahtarı üretiyor.

Yanlış kapsamın "önlenen" sütunundaki büyük sayıları bir kazanç gibi okunamaz. Arıza
penceresinde `takip` kipi 14001 yan etki önlemiş görünüyor; bunun 10.000'i arızasız günde de
oluşan bastırmadır, yani gerçek yan etkinin silinmesidir. Kural şudur: **tekillik anahtarının
kapsamı, iş anlamında ayrı olan iki olayı ayırt edecek kadar geniş olmalıdır**; anahtarı
daraltmak yinelemeyi değil, sistemin kendi işini yok eder.

Alt blok arızalı pencereyi sayıyor. Doğru kapsamda 8750 özgün olay 11.849 teslime dönüşüyor;
fazladan 3099 teslimin 1789'u taşıyıcının yeniden denemesinden, 876'sı devralmada yeniden
sürmeden, 434'ü en az bir kez teslimden geliyor. Defter olmasaydı yan etki 11.250 yerine 15.251
olurdu: **4001 fazladan yan etki**. Bunun içinde 451 yinelenen ücret kalemi ve 451 yinelenen
bildirim var — biri satıcıya iki kez fatura edilen bir teslim, öteki alıcıya iki kez giden bir
teslim iletisidir.

#### Defterin Bedeli

Defter bedava değil. Her yazma önce defteri okur, sonra kendi kaydının yanına bir anahtar satırı
yazar; bu satırlar bir pencere boyunca saklanır.

**DD3 — anahtar kaydı 72 bayt, defter penceresi 24 saat.** Kayıt anahtarı, gövde özetini, zaman
damgasını ve sonuç göstergesini taşır. Pencerenin gerekçesi, bir istemcinin yeniden deneme
zincirini ve devralma sonrası yeniden sürmeyi kapsayacak kadar uzun olmasıdır. Duyarlılığı kayıt
boyunun iki katı, pencerenin üç katı ve bir saatlik pencereyle verilir.

```js
// etkisiz/bedel.mjs — defterin K01 olceginde tuttugu kayit, kapladigi bayt ve satir hizlari
const OLAY = 2_800_000, GONDERI = 400_000;        // K01 hesabi: gunluk durum olayi ve gonderi
const TEPE_YAZMA = 97.22, ARKA_OKUMA = 41.67;     // K01 hesabi: tepe yazma, onbellek arkasi okuma
const GUNLUK_MB = 976, ORAN = 2.33;               // K01 hesabi: gunluk veri artisi, yazma/okuma
const KAYIT = 72, SAAT = 24;                      // DD3: anahtar kaydi bayti ve defter penceresi
const yazan = OLAY + GONDERI;

console.log(`gunluk anahtar isteyen yazma ${yazan.toLocaleString("tr-TR")} ` +
  `(${OLAY.toLocaleString("tr-TR")} durum olayi + ${GONDERI.toLocaleString("tr-TR")} gonderi)`);
console.log(`\n${"pencere".padStart(9)}${"kayit bayt".padStart(12)}${"tutulan kayit".padStart(15)}` +
  `${"defter MB".padStart(12)}${"gunluk artisin".padStart(16)}`);
for (const [s, b] of [[SAAT, KAYIT], [SAAT, KAYIT * 2], [SAAT * 3, KAYIT], [1, KAYIT]]) {
  const kayit = (yazan * s) / 24, mb = (kayit * b) / 1e6;
  console.log(`${`${s} saat`.padStart(9)}${String(b).padStart(12)}` +
    `${Math.round(kayit).toLocaleString("tr-TR").padStart(15)}${mb.toFixed(2).padStart(12)}` +
    `${`%${((100 * mb) / GUNLUK_MB).toFixed(2)}`.padStart(16)}`);
}

const yaz2 = TEPE_YAZMA * 2, oku2 = ARKA_OKUMA + TEPE_YAZMA;
console.log(`\ntepe yazma satir/s ${TEPE_YAZMA} -> ${yaz2.toFixed(2)} (${(yaz2 / TEPE_YAZMA).toFixed(2)} kat)`);
console.log(`onbellek arkasi okuma/s ${ARKA_OKUMA} -> ${oku2.toFixed(2)} (${(oku2 / ARKA_OKUMA).toFixed(2)} kat)`);
console.log(`depoda yazma/okuma orani ${ORAN} -> ${(yaz2 / oku2).toFixed(2)}`);

const ONLENEN = 4001, UCRET = 451;                // olc.mjs: pencere basina onlenen yan etki ve
console.log(`\n${"DD1 pencere/ay".padStart(15)}${"onlenen yan etki".padStart(18)}` +  // yinelenen teslim
  `${"yinelenen ucret kalemi".padStart(23)}${"gunluk kalemin".padStart(16)}`);
for (const n of [2, 4])
  console.log(`${n.toFixed(0).padStart(15)}${(n * ONLENEN).toLocaleString("tr-TR").padStart(18)}` +
    `${(n * UCRET).toLocaleString("tr-TR").padStart(23)}` +
    `${`%${((100 * n * UCRET) / (GONDERI * 30)).toFixed(5)}`.padStart(16)}`);
console.log(`yanlis kapsam bedeli: takip+durum kipinde gunde ` +
  `${((OLAY * 2) / 7).toLocaleString("tr-TR")} gecerli olay bastirilir, ` +
  `takip kipinde ${((OLAY * 6) / 7).toLocaleString("tr-TR")}`);
```

```
gunluk anahtar isteyen yazma 3.200.000 (2.800.000 durum olayi + 400.000 gonderi)

  pencere  kayit bayt  tutulan kayit   defter MB  gunluk artisin
  24 saat          72      3.200.000      230.40          %23.61
  24 saat         144      3.200.000      460.80          %47.21
  72 saat          72      9.600.000      691.20          %70.82
   1 saat          72        133.333        9.60           %0.98

tepe yazma satir/s 97.22 -> 194.44 (2.00 kat)
onbellek arkasi okuma/s 41.67 -> 138.89 (3.33 kat)
depoda yazma/okuma orani 2.33 -> 1.40

 DD1 pencere/ay  onlenen yan etki yinelenen ucret kalemi  gunluk kalemin
              2             8.002                    902        %0.00752
              4            16.004                  1.804        %0.01503
yanlis kapsam bedeli: takip+durum kipinde gunde 800.000 gecerli olay bastirilir, takip kipinde 2.400.000
```

#### İki Günün Sayısı

**Arızasız günün bedeli üç kalemdir.** Defter 3.200.000 kayıt tutar ve 230,40 MB yer kaplar; bu,
K01'in 976 MB'lık günlük veri artışının yüzde 23,61'idir. Tepe yazma satır hızı 97,22'den
194,44'e, yani tam iki katına çıkar. Okuma tarafına anahtar araması eklenir: önbellek arkası
okuma 41,67'den 138,89'a çıkar, 3,33 kat. Depoda yazma/okuma oranı 2,33'ten 1,40'a **iner** —
sayı küçüldü diye yük azalmadı; defter her iki tarafı da büyüttü, okuma tarafını daha çok.

Duyarlılık pencerede toplanıyor. Pencere 24 saatten 72 saate çıktığında defter 691,20 MB'a, yani
günlük artışın yüzde 70,82'sine ulaşıyor; bir saatlik pencerede 9,60 MB ve yüzde 0,98'de kalıyor.
Kayıt boyunu iki katına çıkarmak aynı etkiyi yapmıyor: 460,80 MB. **Defterin bedelini kayıt
boyu değil pencere belirler**, çünkü pencere hem kayıt sayısını hem saklama süresini çarpar.

**Arızalı günün kazancı iki kalemdir.** DD1 ile ayda 2 pencere, pencere başına 4001 önlenen yan
etki, ayda 8002. Bunun 902'si yinelenen ücret kalemidir ve K01'in günde 400.000 kalemine oranı
yüzde 0,00752'dir. Oran küçüktür ve kalıbı savunan sayı bu değildir: 902 yinelenen ücret kalemi
902 yanlış faturalanmış teslim, yani 902 mutabakat uyuşmazlığıdır; aynı sayıda alıcı da ikinci
kez teslim iletisi alır. DD1 iki katına çıktığında 1804 olur. Yan etkinin sayısı yüzdeyle değil
**tanesiyle** okunur, çünkü her tane bir düzeltme işi doğurur.

#### Özet

- Yineleme tek kaynaktan gelmez: 90 saniyelik pencerede 3099 fazladan teslimin 1789'u yeniden
  denemeden, 876'sı devralmada yeniden sürmeden, 434'ü en az bir kez teslimden geldi.
- Defter olmadan yan etki 11.250 yerine 15.251 olurdu; önlenen 4001 yan etkinin 451'i yinelenen
  ücret kalemi, 451'i yinelenen bildirimdir.
- Tekillik anahtarının kapsamı bir bastırma kararıdır: `takip` kipi arızasız günde 7500,
  `takip+durum` kipi 2500 geçerli olayı bastırıyor; K01 ölçeğinde bu günde 2.400.000 ve 800.000
  olay eder.
- Arızasız günün bedeli: 3.200.000 defter kaydı, 230,40 MB (günlük artışın yüzde 23,61'i), tepe
  yazma satırı 2,00 kat, önbellek arkası okuma 3,33 kat.
- Bedeli pencere belirler: 72 saatlik pencere defteri 691,20 MB'a çıkarıyor, bir saatlik pencere
  9,60 MB'ta tutuyor; kayıt boyunu ikiye katlamak 460,80 MB veriyor.
- Arızalı günün kazancı ayda 8002 önlenen yan etki ve 902 yinelenen ücret kalemidir; günlük
  kalemin yüzde 0,00752'si, ama 902 ayrı düzeltme işi.

#### Sonraki Adım

Defter yinelemeyi durdurdu, ama yalnız **aynı** işin ikinci kez yapılmasını. Tatbikatın bıraktığı
ikinci sorun yerinde duruyor: yarıda kesilen bir iş akışının **tamamlanmış adımları** hâlâ geri
alınmıyor. Ücretlendirme işi üçüncü adımda düşerse ilk iki adımın etkisi kesinleşmiş kalır ve
bunlar yinelenmiş değil, eksik kalmış etkilerdir; tekillik anahtarı bu duruma hiçbir şey söylemez.
Sonraki ders geri alınamayan adımların dengelenmesini ele alır: telafi edilemeyen bir adımın
sıralamada nereye konacağı, telafi çağrısının kendisi başarısız olduğunda kaç işin askıda kaldığı
ve geri sarma penceresinde ara durumun ne kadar süre göründüğü.

### Telafi Edici İşlemler

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/telafi-edici-islemler

Geri alınamayan adımların dengelenmesi: yirmi dört sıralamadan yalnız ikisinin bağımlılıklara uyması, geri alınamaz adımın sona taşınamadığı durum, telafi çağrısının kendi arızasının günde 2,979 işi askıda bırakması ve ara durum penceresinin geri sarmadan değil askıda kalan işten gelmesi.

Önceki ders yinelemeyi durdurdu: tekillik anahtarı aynı işin ikinci kez yapılmasını engelledi.
Tatbikatın bıraktığı ikinci sorun yerinde duruyor. Gün sonu ücretlendirme iş akışı üçüncü adımda
düştüğünde ilk iki adımın etkisi kesinleşmiş kalır; bunlar yinelenmiş değil, **yarım kalmış**
etkilerdir ve tekillik anahtarı onlara hiçbir şey söylemez.

**Telafi edici işlem** (compensating transaction), tamamlanmış bir adımın etkisini ters yönde
bir işlemle dengeleyen adımdır — Veri Erişim Katmanı kursundaki **telafi adımı** ile aynı
kavramdır, orada saga düzeni içinde kurulmuş ve telafinin kendisinin de başarısız olabileceği
ölçülmüştü; burada mekanik tekrarlanmaz. Adın benzerliği yanıltmasın: Eşzamansız İşleme
kursundaki **telafi politikası** (catch-up policy) geri kalmış bir tüketicinin nasıl yetişeceğine
dair ayrı bir karardır. Bu dersin üç sorusu vardır: telafi edilemeyen adım sıralamada nereye
konabilir, telafi çağrısı başarısız olduğunda kaç iş askıda kalır ve geri sarma penceresinde ara
durum ne kadar süre görünür.

#### Sıralama Serbest Değil

Gün sonu ücretlendirme dört adımdır: dönemi kapatmak, fatura satırını yazmak, tahsilat kaydını
açmak ve satıcıya bildirim göndermek. İkisi geri alınamaz. **Dönem kapatma** geri alınamaz,
çünkü kapanan dönemin yeniden açılması arada gelen taşıyıcı olaylarını kapsam dışına düşürür ve
aynı gün iki kez faturalanabilir hale gelir. **Satıcı bildirimi** geri alınamaz, çünkü gönderilmiş
bir bildirim ancak ikinci bir bildirimle düzeltilebilir.

Kural bilinir: telafi edilemeyen adım sıralamanın sonuna konur. Sorun, adımların **bağımlılık**
taşımasıdır. Fatura satırı dönem kapanmadan yazılamaz, tahsilat kaydı fatura satırı olmadan
açılamaz, bildirim fatura satırından önce gönderilemez. Kaç sıralamanın hem bağımlılıklara uyup
hem kuralı sağladığı sayılabilir bir sorudur.

```js
// telafi/akis.mjs — gun sonu ucretlendirme is akisinin surec ici modeli.
// Servis, ag ve depo yoktur; adimlar birer nesne, geri sarma bir dongudur.
// Telafi edici islem, M16/K04'un telafi adimiyla ayni seydir; mekanigi orada kuruldu.

export const ADIM = [
  { ad: "donem-kapat", telafi: null, once: [] },                       // geri alinamaz
  { ad: "fatura-satiri", telafi: "satiri-iptal-et", once: ["donem-kapat"] },
  { ad: "tahsilat-kaydi", telafi: "kaydi-geri-al", once: ["fatura-satiri"] },
  { ad: "satici-bildirimi", telafi: null, once: ["fatura-satiri"] },   // geri alinamaz
];

export function* dizilisler(adimlar) {                 // butun siralamalar
  if (adimlar.length === 0) { yield []; return; }
  for (let i = 0; i < adimlar.length; i += 1)
    for (const k of dizilisler(adimlar.filter((_, j) => j !== i)))
      yield [adimlar[i], ...k];
}

export const gecerli = (d) => d.every((a, i) =>
  a.once.every((o) => d.slice(0, i).some((x) => x.ad === o)));

// Bir kosum: k. adimda hata cikar, tamamlananlar tersten telafi edilir.
// telafiHata: telafi cagrisinin basarisizlik olasiligi; deneme: telafi deneme sayisi.
export function kosum(dizilis, k, { telafiHata, deneme, rnd }) {
  const tamam = dizilis.slice(0, k);
  const r = { telafisiz: 0, telafiCagrisi: 0, askida: 0, tur: 0 };
  for (const a of [...tamam].reverse()) {
    r.tur += 1;
    if (a.telafi === null) { r.telafisiz += 1; continue; }
    let oldu = false;
    for (let d = 0; d < deneme && !oldu; d += 1) {
      r.telafiCagrisi += 1;
      if (d > 0) r.tur += 1;
      oldu = rnd() >= telafiHata;
    }
    if (!oldu) r.askida += 1;
  }
  return r;
}

export function uretec(tohum) {              // 32 bitlik dogrusal esitlikli uretec, tohum acik
  let s = tohum >>> 0;
  return () => { s = (Math.imul(s, 1103515245) + 12345) >>> 0; return s / 4294967296; };
}
```

**DD5 — telafi çağrısının başarısızlık olasılığı 0,05.** Gerekçesi: telafi de bir uzak çağrıdır
ve bir arızanın hemen ardından koşar; hedef servis o anda hâlâ bozuk olabilir, bu yüzden olağan
çağrıdan daha yüksek bir hata payı taşır. Duyarlılığı deneme sayısı taranarak verilir. Sayı bir
**varsayımdır** ve K01'in tablosuna eklenmez.

```js
// telafi/olc.mjs — gecerli siralamalarda telafisiz kalan adim ve geri sarma turu
import { ADIM, dizilisler, gecerli, kosum, uretec } from "./akis.mjs";

const D = [...dizilisler(ADIM)];
const G = D.filter(gecerli);
console.log(`${D.length} siralamanin ${G.length} tanesi bagimliliklara uyuyor`);
console.log(`geri alinamaz adim: ${ADIM.filter((a) => a.telafi === null).map((a) => a.ad).join(", ")}`);

const yok = () => 1;                     // telafi hatasiz kosum: rnd() = 1 >= hata
console.log(`\n${"siralama".padEnd(58)}${"telafisiz".padStart(10)}${"tur".padStart(6)}`);
const ozet = [];
for (const d of G) {
  let telafisiz = 0, tur = 0;
  for (let k = 1; k <= ADIM.length; k += 1) {           // k. adimda hata
    const r = kosum(d, k - 1, { telafiHata: 0, deneme: 1, rnd: yok });
    telafisiz += r.telafisiz; tur += r.tur;
  }
  ozet.push([d.map((a) => a.ad).join(" > "), telafisiz, tur]);
  console.log(`${ozet.at(-1)[0].padEnd(58)}${String(telafisiz).padStart(10)}${String(tur).padStart(6)}`);
}

const en = G[ozet.findIndex((o) => o[1] === Math.min(...ozet.map((x) => x[1])))];
console.log(`\nsecilen siralama: ${en.map((a) => a.ad).join(" > ")}`);
console.log(`${"hatanin ciktigi adim".padEnd(24)}${"tamamlanan".padStart(12)}${"telafi edilen".padStart(15)}` +
  `${"telafisiz".padStart(11)}${"geri sarma turu".padStart(17)}`);
for (let k = 1; k <= ADIM.length; k += 1) {
  const r = kosum(en, k - 1, { telafiHata: 0, deneme: 1, rnd: yok });
  console.log(`${`${k}. (${en[k - 1].ad})`.padEnd(24)}${String(k - 1).padStart(12)}` +
    `${String(r.telafiCagrisi).padStart(15)}${String(r.telafisiz).padStart(11)}${String(r.tur).padStart(17)}`);
}

// DD5: telafi cagrisinin basarisizlik olasiligi 0,05. Deneme sayisi taranir.
const N = 100_000, HATA = 0.05;
console.log(`\n${N} kosum, DD5 telafi hatasi ${HATA}; hata adimi esit dagilimla secilir`);
console.log(`${"telafi denemesi".padStart(16)}${"askida is".padStart(12)}${"oran".padStart(10)}` +
  `${"telafi cagrisi/is".padStart(19)}${"ort. geri sarma turu".padStart(22)}`);
for (const deneme of [1, 2, 3]) {
  const rnd = uretec(20260730);
  let askida = 0, cagri = 0, tur = 0;
  for (let i = 0; i < N; i += 1) {
    const k = i % ADIM.length;                          // hata adimi esit dagilimla
    const r = kosum(en, k, { telafiHata: HATA, deneme, rnd });
    askida += r.askida > 0 ? 1 : 0; cagri += r.telafiCagrisi; tur += r.tur;
  }
  console.log(`${String(deneme).padStart(16)}${String(askida).padStart(12)}` +
    `${(askida / N).toFixed(5).padStart(10)}${(cagri / N).toFixed(3).padStart(19)}` +
    `${(tur / N).toFixed(3).padStart(22)}`);
}
```

```
24 siralamanin 2 tanesi bagimliliklara uyuyor
geri alinamaz adim: donem-kapat, satici-bildirimi

siralama                                                   telafisiz   tur
donem-kapat > fatura-satiri > tahsilat-kaydi > satici-bildirimi         3     6
donem-kapat > fatura-satiri > satici-bildirimi > tahsilat-kaydi         4     6

secilen siralama: donem-kapat > fatura-satiri > tahsilat-kaydi > satici-bildirimi
hatanin ciktigi adim      tamamlanan  telafi edilen  telafisiz  geri sarma turu
1. (donem-kapat)                   0              0          0                0
2. (fatura-satiri)                 1              0          1                1
3. (tahsilat-kaydi)                2              1          1                2
4. (satici-bildirimi)              3              2          1                3

100000 kosum, DD5 telafi hatasi 0.05; hata adimi esit dagilimla secilir
 telafi denemesi   askida is      oran  telafi cagrisi/is  ort. geri sarma turu
               1        3724   0.03724              0.750                 1.500
               2         214   0.00214              0.788                 1.538
               3           8   0.00008              0.790                 1.540
```

Bu sayılar **ölçüm** sınıfındadır: süreç içi bir modelden ve tohumu 20260730 olan bir üreteçten
gelirler, aynı tohumla yeniden üretilirler.

#### Kural Ancak Bağımlılığın İzin Verdiği Kadar Uygulanır

Yirmi dört sıralamanın yirmi ikisi bağımlılık ihlal ediyor; geriye iki sıralama kalıyor ve ikisi
de `donem-kapat` ile başlıyor. Bu, kuralın sınırıdır: **geri alınamaz iki adımdan biri sona
taşınamaz, çünkü öteki üç adım ona bağımlıdır.** Bildirim sona alınabilir, dönem kapatma
alınamaz.

Alt tablo bunun bedelini adım adım gösteriyor. Hata birinci adımda çıkarsa hiçbir şey
tamamlanmamıştır; telafisiz kalan adım 0. Hata ikinci, üçüncü ya da dördüncü adımda çıkarsa
dönem kapalıdır ve kapalı kalır: her üç durumda da telafisiz adım 1. Sıralamayı değiştirmek bu
sayıyı düşürmüyor, yalnız ikinci geri alınamaz adımın konumunu oynatıyor — bildirim üçüncü sıraya
alındığında toplam telafisiz adım 3'ten 4'e çıkıyor.

Buradan çıkan tasarım kuralı sıralamayla ilgili değil. Sona taşınamayan bir geri alınamaz adım
varsa **onu geri alınabilir kılmak** tek çıkıştır: dönem kapatma bir silme değil, bir bayrak
yazması olarak tanımlanırsa telafisi vardır. Sıralama kuralı bir yerleştirme aracıdır, adım
tasarımının yerini tutmaz.

#### Askıda Kalan İş ve Ara Durum Penceresi

Alt blok telafinin kendi arızasını sayıyor. Tek denemede işlerin yüzde 3,724'ü **askıda** kalıyor:
telafi çağrısı düştü, adımın etkisi duruyor ve iş ne tamamlanmış ne geri alınmış durumda. İkinci
deneme oranı 0,00214'e, üçüncü 0,00008'e indiriyor. Karşılığında iş başına telafi çağrısı
0,750'den 0,790'a, geri sarma turu 1,500'den 1,540'a çıkıyor — yani ikinci deneme yüzde 5 daha
fazla çağrıya karşılık askıda kalan işi **on yedi kat** azaltıyor.

Ara durum penceresi, geri sarma sürerken fatura satırının "kesilmiş" görünmesidir. Bu pencerenin
uzunluğu turla ölçülür; tura süre vermek için bir çevrim katsayısı gerekir.

**DD6 — bir geri sarma turu 0,25 saniye.** Gerekçesi: tur bir uzak çağrı ile onun kesinleşmesidir.
Duyarlılığı dört katıyla verilir. **DD7 — askıda kalan iş 4 saat içinde kapatılır**, yani K01'in
V10 toplu penceresi kadar; ücretlendirme işinin penceresi budur.

```js
// telafi/bedel.mjs — olculen oranlarin K01 olceginde gunluk sayilara cevrilmesi
const FATURA = 4000;                        // K01 hesabi: gunluk fatura satiri
const KK2 = 0.02;                           // M19/K03 koreografi dersinin varsayimi: is akisi hata orani
const TUR = 0.25, ASKIDA_SAAT = 4;          // DD6 tur suresi, DD7 askida isin kapatilma suresi
const hatali = FATURA * KK2;

console.log(`gunluk is akisi ${FATURA}, KK2 = ${KK2} -> hatali ${hatali}/gun`);
console.log(`\n${"siralama".padEnd(22)}${"telafisiz adim/gun".padStart(20)}${"yilda".padStart(9)}`);
for (const [ad, oran] of [["bildirim sonda", 3 / 4], ["bildirim ucuncu", 4 / 4]])
  console.log(`${ad.padEnd(22)}${(hatali * oran).toFixed(1).padStart(20)}` +
    `${(hatali * oran * 365).toFixed(0).padStart(9)}`);

// olc.mjs olcumleri: askida is orani ve ortalama geri sarma turu, telafi denemesine gore
const OLCUM = [[1, 0.03724, 1.500], [2, 0.00214, 1.538], [3, 0.00008, 1.540]];
console.log(`\n${"deneme".padStart(7)}${"askida is/gun".padStart(15)}${"yilda".padStart(8)}` +
  `${"geri sarma s".padStart(14)}${"ara durum s/gun".padStart(17)}${"askidan gelen saat/gun".padStart(24)}`);
for (const [deneme, oran, tur] of OLCUM) {
  const askida = hatali * oran, sarma = tur * TUR;
  console.log(`${String(deneme).padStart(7)}${askida.toFixed(3).padStart(15)}` +
    `${(askida * 365).toFixed(0).padStart(8)}${sarma.toFixed(3).padStart(14)}` +
    `${(hatali * sarma).toFixed(1).padStart(17)}${(askida * ASKIDA_SAAT).toFixed(3).padStart(24)}`);
}
const [, o1, t1] = OLCUM[0];
const kat = (t) => (hatali * o1 * ASKIDA_SAAT * 3600) / (hatali * t1 * t);
console.log(`\ntek denemede askidan gelen / geri sarmadan gelen = ${kat(TUR).toFixed(0)} kat`);
console.log(`DD6 duyarliligi: tur suresi ${TUR} s yerine ${TUR * 4} s ise ara durum ` +
  `${(hatali * t1 * TUR * 4).toFixed(1)} s/gun, oran ${kat(TUR * 4).toFixed(0)} kat`);
console.log(`\narizasiz gunun bedeli: 4 adimin 2'si telafi islevi tasiyor, gunde ` +
  `${(FATURA * 2).toLocaleString("tr-TR")} yazilmis telafi yolu; kosulan telafi cagrisi ` +
  `${(hatali * 0.75).toFixed(0)}/gun, is akisi basina ${(0.75 * KK2).toFixed(4)}`);
```

```
gunluk is akisi 4000, KK2 = 0.02 -> hatali 80/gun

siralama                telafisiz adim/gun    yilda
bildirim sonda                        60.0    21900
bildirim ucuncu                       80.0    29200

 deneme  askida is/gun   yilda  geri sarma s  ara durum s/gun  askidan gelen saat/gun
      1          2.979    1087         0.375             30.0                  11.917
      2          0.171      62         0.385             30.8                   0.685
      3          0.006       2         0.385             30.8                   0.026

tek denemede askidan gelen / geri sarmadan gelen = 1430 kat
DD6 duyarliligi: tur suresi 0.25 s yerine 1 s ise ara durum 120.0 s/gun, oran 358 kat

arizasiz gunun bedeli: 4 adimin 2'si telafi islevi tasiyor, gunde 8.000 yazilmis telafi yolu; kosulan telafi cagrisi 60/gun, is akisi basina 0.0150
```

#### İki Günün Sayısı

**Arızasız günün bedeli kod yolundadır.** Dört adımın ikisi bir telafi işlevi taşımak zorundadır
ve bu işlevler her iş akışı tanımında durur: günde 4000 iş akışı için 8000 yazılmış telafi yolu.
Bunların koşulma sayısı çok küçüktür — iş akışı başına 0,0150, günde 60 çağrı. Bedel çalışma
zamanı yükü değil, **sınanmayan koddur**: yılda 21.900 kez yürüyen bir yolun yanında, yüzde
1,5'lik bir olasılıkla yürüyen bir yol taşınıyor. Ayrıca dönem kapatmanın geri alınamaz olması
arızasız günde de bir kısıt üretir; kapanan dönem üzerinde düzeltme yapılamaz.

**Arızalı günün kazancı iki sayıdır.** KK2 = 0,02 ile günde 80 iş akışı hata veriyor. Sıralama
kuralı uygulandığında telafisiz kalan adım günde 60, yılda 21.900; bildirim üçüncü sıraya
alınırsa 80 ve 29.200. Sıralama tek başına yılda 7300 telafisiz adım fark ettiriyor. Telafi
denemesi bir arttırıldığında askıda kalan iş günde 2,979'dan 0,171'e, yılda 1087'den 62'ye
iniyor.

Ara durum penceresinin iki kaynağı var ve büyüklükleri karşılaştırılamaz. Geri sarmanın kendisi
günde toplam **30,0 saniye** ara durum üretiyor. Askıda kalan işler ise günde **11,917 saat** —
1430 kat. DD6 dört katına çıkarılsa bile oran 358 kat kalıyor, yani sonuç tur süresi
varsayımına duyarlı değil. **Ara durum penceresini geri sarmanın hızı değil, telafinin kendi
arızası belirler**; pencereyi kısaltmak isteyen taraf tur süresini değil, telafi deneme sayısını
oynatmalıdır.

#### Özet

- Yirmi dört sıralamanın yalnız ikisi bağımlılıklara uyuyor ve ikisi de geri alınamaz `donem-kapat`
  adımıyla başlıyor: sona taşıma kuralı bu adıma uygulanamıyor.
- Hata ikinci, üçüncü ya da dördüncü adımda çıktığında telafisiz kalan adım her durumda 1; sona
  taşınamayan bir adımı kurtaran şey sıralama değil, adımı geri alınabilir tasarlamaktır.
- Bildirimin yeri yılda 7300 telafisiz adım fark ettiriyor: sonda 60/gün ve 21.900/yıl, üçüncü
  sırada 80/gün ve 29.200/yıl.
- Telafi kendi arızasını taşır: DD5 = 0,05 ile tek denemede işlerin yüzde 3,724'ü askıda kalıyor;
  ikinci deneme oranı 0,00214'e indiriyor ve iş başına çağrıyı 0,750'den 0,790'a çıkarıyor.
- Ara durum penceresinin ezici kısmı geri sarmadan değil askıda kalan işten geliyor: günde 30,0
  saniyeye karşı 11,917 saat, 1430 kat; DD6 dört katına çıksa bile 358 kat.
- Arızasız günün bedeli 8000 yazılmış telafi yoludur ve bunların yalnız 60'ı günde koşar; taşınan
  şey çalışma zamanı yükü değil, seyrek yürüyen koddur.

#### Sonraki Adım

Telafi, iş akışının **adımlarını** doğru tuttu. Aynı iş akışının taşıdığı **veri** hiç
sorulmadı. Taşıyıcı bir teslimi bildirirken yanına teslim kanıtını da koyar: alıcının imzası ya
da teslim noktasının görüntüsü. Bu ek, durum olayının kaydını K01'in 220 baytından çok daha
büyük bir şeye çevirir ve o şey kuyruğun içinden geçer, her tüketiciye kopyalanır, her yeniden
teslimde yeniden taşınır. Sonraki ders büyük yükün iletiden çıkarılmasını ele alır: iletinin
boyutu, kuyruk üzerinden geçen bayt, yükün ayrı depoda ne kadar yaşayacağı ve yük silindikten
sonra elde kalan başvurunun kaç kez sarktığı.

### Talep Fişi Kalıbı

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/talep-fisi-kalibi

Büyük yükün ileti dışında taşınması: teslim kanıtının iletiyi 40.220 bayta çıkarması, fişin ileti baytını 141,6 kat düşürmesi, kuyruk üzerindeki birikmenin 3016,5 MB'den 21,3 MB'ye inmesi, kanıtın saklama tarafında hiç küçülmemesi ve tek yazmanın ikiye bölünmesiyle doğan yetim yük ile sarkan fiş.

Önceki iki ders iş akışının adımlarını doğru tuttu: yineleme bastırıldı, yarım kalan adımlar
dengelendi. İş akışının taşıdığı **veri** hiç sorulmadı. Taşıyıcı bir teslimi bildirirken yanına
teslim kanıtını koyar — alıcının imzası ya da teslim noktasının görüntüsü. Bu ek, K01'in 220
baytlık durum olayı kaydını başka bir mertebeye taşır ve o bayt kuyruğun içinden geçer, her
tüketiciye kopyalanır, her yeniden teslimde yeniden taşınır.

**Talep fişi** (claim check), büyük yükü ayrı bir depoya yazıp iletide yalnız o yükün başvurusunu
taşıyan yerleşimdir. Bu dersin ölçüleri dörttür: iletinin boyutu, kuyruk üzerinden geçen bayt,
yükün ayrı depoda yaşama süresi ve fişin sarkması — yükün silinmiş, fişin elde kalmış olması.

#### İki Yazma, Tek İşlem Sınırı Yok

**DD8 — teslim kanıtı 40.000 bayt.** Gerekçesi: kanıt sıkıştırılmış bir imza görüntüsüdür ve
K01'in 900 baytlık gönderi kaydının iki mertebe üstündedir. Duyarlılığı ileti baytı oranıyla
zaten görünür. **DD9 — talep fişi kaydı 64 bayt**: depo adı, nesne anahtarı ve özet.

Kalıbın gizli maliyeti buradan başlar. İliştirilmiş yerleşimde tek bir yazma vardır: ileti
kuyruğa gider ve kanıt onun içindedir. Fişli yerleşimde **iki yazma** vardır — önce kanıt depoya,
sonra ileti kuyruğa — ve ikisinin ortak bir işlem sınırı yoktur. Veri Erişim Katmanı kursunun
dağıtık işlem sorunu tam olarak budur. İki yeni arıza kipi doğar: **yetim yük** (kanıt yazıldı,
ileti yazılamadı) ve **sarkan fiş** (ileti elde, kanıt silinmiş).

```js
// fis/kuyruk.mjs — teslim kaniti tasiyan olay akisinin surec ici modeli.
// Gercek kuyruk, depo ve ag yoktur: kuyruk bir dizi, yuk deposu bir kume, bayt sayilir.

export const OLAY = 220, KANIT = 40_000, FIS = 64;   // K01 V6; DD8 kanit; DD9 fis kaydi

export function uretec(tohum) {              // 32 bitlik dogrusal esitlikli uretec, tohum acik
  let s = tohum >>> 0;
  return () => { s = (Math.imul(s, 1103515245) + 12345) >>> 0; return s / 4294967296; };
}

// yerlesim: "ilistir" = kanit iletinin icinde; "fis" = kanit depoda, ileti fis tasir
// silme:    "hemen"   = tuketici isleyince siler; "sure" = yasam suresi doldurur
export function kos({ n, yerlesim, silme, uretiCokme, onaysizCokme, tohum }) {
  const rnd = uretec(tohum);
  const fisli = yerlesim === "fis";
  const ileti = fisli ? OLAY + FIS : OLAY + KANIT;
  const depo = new Set(), kuyruk = [];
  const s = { ileti, tasinanBayt: 0, teslim: 0, kayipOlay: 0, yetimYuk: 0,
    sarkanFis: 0, islenen: 0, depodaKalan: 0 };

  for (let i = 0; i < n; i += 1) {
    if (fisli) depo.add(i);                           // once yuk yazilir
    const coktu = rnd() < uretiCokme;                 // sonra ileti yazilir; arasinda cokme
    if (coktu) { if (fisli) s.yetimYuk += 1; else s.kayipOlay += 1; continue; }
    kuyruk.push({ no: i, deneme: 0 });
  }
  while (kuyruk.length > 0) {
    const m = kuyruk.shift();
    s.tasinanBayt += ileti; s.teslim += 1;            // her teslim iletiyi bastan tasir
    if (fisli && !depo.has(m.no)) { s.sarkanFis += 1; continue; }
    s.islenen += 1;
    if (fisli && silme === "hemen") depo.delete(m.no);
    if (rnd() < onaysizCokme && m.deneme === 0) kuyruk.push({ no: m.no, deneme: 1 });
  }
  s.depodaKalan = fisli ? depo.size : 0;
  return s;
}
```

Arıza senaryosu adıyla tanımlanır. **DD10 — arıza penceresinde üreticinin iki yazma arasında
çökme olasılığı 0,005, tüketicinin onaydan önce çökme olasılığı 0,01.** Gerekçesi: birinci
pencere iki uzak yazma arasındaki kısa aralık, ikincisi işleme ile onay arasındaki aralıktır ve
ikincisi daha uzundur. İkisi de varsayımdır, K01'in tablosuna eklenmez.

```js
// fis/olc.mjs — dort yerlesim, ariza yokken ve varken; ileti bayti ile sarkma sayilir
import { kos, OLAY, KANIT, FIS } from "./kuyruk.mjs";

const N = 100_000;
const DURUM = [["arizasiz gun", 0, 0], ["ariza penceresi (DD10)", 0.005, 0.01]];
const YER = [["ilistir", "-"], ["fis", "hemen"], ["fis", "sure"]];

console.log(`ileti bayti: ilistirilmis ${OLAY + KANIT}, fisli ${OLAY + FIS} ` +
  `(K01 V6 = ${OLAY} bayt olay, DD8 = ${KANIT} bayt kanit, DD9 = ${FIS} bayt fis)`);
for (const [ad, uretiCokme, onaysizCokme] of DURUM) {
  console.log(`\n${ad}: ${N} teslim olayi, uretici cokme ${uretiCokme}, onaysiz cokme ${onaysizCokme}`);
  console.log(`${"yerlesim".padEnd(16)}${"teslim".padStart(9)}${"tasinan MB".padStart(12)}` +
    `${"kayip olay".padStart(12)}${"yetim yuk".padStart(11)}${"sarkan fis".padStart(12)}` +
    `${"islenen".padStart(9)}${"depoda".padStart(9)}`);
  for (const [yerlesim, silme] of YER) {
    const r = kos({ n: N, yerlesim, silme, uretiCokme, onaysizCokme, tohum: 20260730 });
    console.log(`${`${yerlesim} ${silme}`.padEnd(16)}${String(r.teslim).padStart(9)}` +
      `${(r.tasinanBayt / 1e6).toFixed(2).padStart(12)}${String(r.kayipOlay).padStart(12)}` +
      `${String(r.yetimYuk).padStart(11)}${String(r.sarkanFis).padStart(12)}` +
      `${String(r.islenen).padStart(9)}${String(r.depodaKalan).padStart(9)}`);
  }
}
```

```
ileti bayti: ilistirilmis 40220, fisli 284 (K01 V6 = 220 bayt olay, DD8 = 40000 bayt kanit, DD9 = 64 bayt fis)

arizasiz gun: 100000 teslim olayi, uretici cokme 0, onaysiz cokme 0
yerlesim           teslim  tasinan MB  kayip olay  yetim yuk  sarkan fis  islenen   depoda
ilistir -          100000     4022.00           0          0           0   100000        0
fis hemen          100000       28.40           0          0           0   100000        0
fis sure           100000       28.40           0          0           0   100000   100000

ariza penceresi (DD10): 100000 teslim olayi, uretici cokme 0.005, onaysiz cokme 0.01
yerlesim           teslim  tasinan MB  kayip olay  yetim yuk  sarkan fis  islenen   depoda
ilistir -          100495     4041.91         492          0           0   100495        0
fis hemen          100495       28.54           0        492         987    99508      492
fis sure           100495       28.54           0        492           0   100495   100000
```

Bu sayılar **ölçüm** sınıfındadır: süreç içi bir modelden, tohumu 20260730 olan bir üreteçten
gelirler.

#### Silme Politikası Bir Doğruluk Kararıdır

Üst tablo ileti baytını veriyor: iliştirilmiş yerleşim yüz bin olay için 4022,00 MB taşıyor,
fişli yerleşim 28,40 MB. Oran, ileti baytlarının oranıdır ve arıza yokken başka hiçbir fark yok.

Alt tablo asıl ayrımı yapıyor ve dikkat isteyen sütun `islenen`. İliştirilmiş yerleşimde
üreticinin çökmesi 492 olayı **tümden düşürüyor** — kanıt ile olay tek yazmadaydı, ikisi birden
gitti. Fişli yerleşimde aynı çökme olayı yine kaybettiriyor ama depoda 492 yetim yük bırakıyor;
kayıp eşit, artık bir de çöp var.

İki silme politikası aynı arızada farklı davranıyor. **Hemen silmede** 987 yeniden teslim
kanıtı bulamıyor ve sarkan fişe dönüşüyor; işlenen sayısı 99.508'de, yani her olay **tam bir
kez** işlenmiş oluyor. **Yaşam süresine bırakmada** sarkan fiş sıfır, ama işlenen 100.495: 987
yeniden teslimin hepsi kanıtı buluyor ve işi yeniden yapıyor.

Bu, kalıbın en az fark edilen sonucudur. Yükün silinme anı, farkında olunmadan bir tekillik
denetimine dönüşür: hemen silme yinelenen işlemeyi engeller ama yeniden teslimi bir hataya
çevirir; yaşam süresine bırakma yeniden teslimi çalıştırır ve yinelenen yan etkiyi **birinci
dersin defterine** havale eder. Doğru kurulum ikisini ayırmaktır — tekillik kararı defterde
verilir, silme kararı depoda; yükün ömrü bir doğruluk mekanizması olarak kullanılmaz.

#### Hesaba Dönüş

**DD11 — kanıt yaşam süresi 7 gün.** Gerekçesi: teslim itirazı teslim gününden sonraki iş günü
içinde gelir ve kanıt o pencerede istenir; itirazsız kanıt saklanmaz. Duyarlılığı 1 ve 30 günle
verilir.

```js
// fis/bedel.mjs — olculen ileti baytlarinin K01 olceginde kuyruga, saklamaya ve sarkmaya cevrilmesi
const V3 = 400_000, V8 = 3, GUN = 86_400;         // K01: gunluk gonderi, tepe carpani
const YAZMA_MBIT = 0.17, ARTIS_MB = 976, SAKLAMA_GB = 712.48;   // K01 hesaplari
const BIRIKME = 525_000, OLAY_PAYI = 7;           // M19/K03 mesaj kuyruklari: en yuksek birikme
const ILISTIR = 40_220, FISLI = 284, KANIT = 40_000;            // fis/olc.mjs olcumu; DD8
const teslim = (V3 / GUN) * V8;                   // her gonderi bir teslim olayi uretir

console.log(`tepe teslim olayi ${teslim.toFixed(4)} olay/s (K01: gunde ${V3} gonderi, tepe carpani ${V8})`);
console.log(`\n${"yerlesim".padEnd(12)}${"ileti bayt".padStart(12)}${"kuyruk Mbit/s".padStart(15)}` +
  `${"K01 yazma girisinin".padStart(21)}${"birikmede MB".padStart(14)}`);
for (const [ad, b] of [["ilistir", ILISTIR], ["fis", FISLI]]) {
  const mbit = (teslim * b * 8) / 1e6, birikme = ((BIRIKME / OLAY_PAYI) * b) / 1e6;
  console.log(`${ad.padEnd(12)}${String(b).padStart(12)}${mbit.toFixed(4).padStart(15)}` +
    `${`${(mbit / YAZMA_MBIT).toFixed(2)} kat`.padStart(21)}${birikme.toFixed(1).padStart(14)}`);
}
console.log(`kuyruk bayti orani ${(ILISTIR / FISLI).toFixed(1)} kat; ` +
  `birikme ${(BIRIKME / OLAY_PAYI).toLocaleString("tr-TR")} kanitli ileti (M19/K03: ${BIRIKME.toLocaleString("tr-TR")} olay / ${OLAY_PAYI})`);

console.log(`\n${"DD11 yasam suresi".padStart(18)}${"depoda kanit".padStart(14)}${"depoda GB".padStart(12)}` +
  `${"K01 saklamanin".padStart(16)}${"gunluk artisin".padStart(16)}`);
for (const gun of [1, 7, 30]) {
  const adet = V3 * gun, gb = (adet * KANIT) / 1e9;
  console.log(`${`${gun} gun`.padStart(18)}${adet.toLocaleString("tr-TR").padStart(14)}` +
    `${gb.toFixed(2).padStart(12)}${`%${((100 * gb) / SAKLAMA_GB).toFixed(2)}`.padStart(16)}` +
    `${`${((gb * 1000) / ARTIS_MB).toFixed(2)} kat`.padStart(16)}`);
}

const SARKAN = 987 / 100_000, YETIM = 492 / 100_000;            // fis/olc.mjs olcumu
console.log(`\nariza penceresi K01 olceginde (gunde ${V3.toLocaleString("tr-TR")} teslim olayi):`);
console.log(`sarkan fis ${(V3 * SARKAN).toFixed(0)}/gun, yetim yuk ${(V3 * YETIM).toFixed(0)}/gun`);
console.log(`yetim yukun bayti ${((V3 * YETIM * KANIT) / 1e6).toFixed(1)} MB/gun, ` +
  `yasam suresi yoksa yilda ${((V3 * YETIM * KANIT * 365) / 1e9).toFixed(2)} GB`);
console.log(`ilistirilmis yerlesimde ayni cokme ${(V3 * YETIM).toFixed(0)} olayi tumden dusuruyor`);
```

```
tepe teslim olayi 13.8889 olay/s (K01: gunde 400000 gonderi, tepe carpani 3)

yerlesim      ileti bayt  kuyruk Mbit/s  K01 yazma girisinin  birikmede MB
ilistir            40220         4.4689            26.29 kat        3016.5
fis                  284         0.0316             0.19 kat          21.3
kuyruk bayti orani 141.6 kat; birikme 75.000 kanitli ileti (M19/K03: 525.000 olay / 7)

 DD11 yasam suresi  depoda kanit   depoda GB  K01 saklamanin  gunluk artisin
             1 gun       400.000       16.00           %2.25       16.39 kat
             7 gun     2.800.000      112.00          %15.72      114.75 kat
            30 gun    12.000.000      480.00          %67.37      491.80 kat

ariza penceresi K01 olceginde (gunde 400.000 teslim olayi):
sarkan fis 3948/gun, yetim yuk 1968/gun
yetim yukun bayti 78.7 MB/gun, yasam suresi yoksa yilda 28.73 GB
ilistirilmis yerlesimde ayni cokme 1968 olayi tumden dusuruyor
```

#### İki Günün Sayısı

**Arızasız günün bedeli üç kalemdir.** Her teslim olayı artık iki yazma ve tüketici tarafında bir
fazladan okuma taşır; tek yazmanın atomikliği kaybedilmiştir. Depoda kanıt DD11 = 7 gün ile
112,00 GB durur, K01'in 712,48 GB'lık saklama satırının yüzde 15,72'si. Ve saklama tarafında
kalıbın **hiçbir kazancı yoktur**: kanıt iliştirilmiş olsa da fişli olsa da aynı 40.000 baytı
kaplar. Talep fişi bir saklama kararı değil, bir **taşıma** kararıdır.

**Arızalı günün kazancı kuyruktadır.** İliştirilmiş yerleşimde tepe teslim akışı kuyruğa 4,4689
Mbit/s bindiriyor — K01'in 0,17 Mbit/s'lik yazma girişinin 26,29 katı. Fişli yerleşimde 0,0316
Mbit/s, yani yazma girişinin 0,19 katı. Asıl fark birikmede görünüyor: Uygulama Katmanı ve Servis
Etkileşimi kursunun ölçtüğü 525.000 olayın yedide biri kanıtlı ileti olduğuna göre kuyruk iliştirilmiş yerleşimde **3016,5 MB**,
fişli yerleşimde **21,3 MB** taşımak zorunda. Kuyruğun sınırlı bir tampon olduğu bir tasarımda bu
141,6 katlık fark, aynı sınırda tutulabilen olay sayısının farkıdır.

Kazancın karşılığı yeni arıza kipleridir. K01 ölçeğinde arıza penceresinde günde 1968 yetim yük
(78,7 MB) ve hemen silme politikasında 3948 sarkan fiş oluşuyor. Yaşam süresi olmadan yetim
yükler yılda 28,73 GB'a çıkar; **DD11 bir saklama parametresi değil, çöp toplama
mekanizmasıdır**. Sarkan fiş ise veri kaybı değildir — 3948'in hepsi zaten işlenmiş işin
yeniden teslimidir — ama tüketici tarafında hata olarak görünür ve ölü ileti yolundan ayrılmazsa
gerçek hataları gizler.

#### Özet

- Teslim kanıtı iletiyi 220 bayttan 40.220 bayta çıkarıyor; talep fişi 284 bayta indiriyor, oran
  141,6 kat.
- Kuyruk yükü: tepe teslim akışı iliştirilmiş yerleşimde 4,4689 Mbit/s (K01 yazma girişinin 26,29
  katı), fişli yerleşimde 0,0316 Mbit/s (0,19 katı).
- Birikmede fark büyüyor: 75.000 kanıtlı iletilik birikme 3016,5 MB yerine 21,3 MB tutuyor.
- Saklama tarafında kalıbın kazancı yok: kanıt DD11 = 7 gün ile 112,00 GB, K01 saklamasının yüzde
  15,72'si; talep fişi taşıma kararıdır, saklama kararı değil.
- Kalıp tek yazmayı ikiye bölüyor ve iki yeni arıza kipi getiriyor: günde 1968 yetim yük (78,7 MB,
  yaşam süresi olmazsa yılda 28,73 GB) ve 3948 sarkan fiş.
- Silme politikası sessizce bir doğruluk kararıdır: hemen silmede işlenen 99.508 (tam bir kez),
  yaşam süresine bırakmada 100.495 (987 yinelenen işleme); ikincisi tekillik defterine dayanır.

#### Sonraki Adım

Kanıt kuyruktan çıktı ama yolun tamamı hâlâ servisin içinden geçiyor. Taşıyıcı kanıtı servise
yüklüyor, servis depoya yazıyor; alıcı kanıtı görmek istediğinde servis depodan okuyup istemciye
aktarıyor. Kuyruktan kaldırılan 40.000 bayt, servisin isteğe bağlı yolunda iki kez geçmeye devam
ediyor ve depo yavaşladığında servisin kendi işçilerini tutuyor. Sonraki ders bu baytı servisin
üzerinden de kaldırmayı ele alır: istemciye doğrudan kaynak erişimi için verilen sınırlı yetki,
servisin üzerinden geçmeyen bayt, açılan yetki penceresi ve kapsamı daraltmanın kaça mal olduğu.

### Vale Anahtarı Kalıbı

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/vale-anahtari-kalibi

Doğrudan kaynak erişimi için sınırlı yetki: kanıt baytının servisin üzerinden kaldırılmasıyla aktarım başına 80.000 baytın 512 bayta inmesi, depo yavaşladığında tutulan yuvanın 64'te doyup 28 aktarımı düşürmesi, açık yetki penceresinin anahtar süresiyle büyümesi ve kapsam daraltmanın getirisinin doğrusal olmaması.

Talep fişi kanıtı kuyruğun dışına çıkardı ama yolun tamamı hâlâ servisin içinden geçiyor.
Taşıyıcı kanıtı servise yüklüyor, servis depoya yazıyor; alıcı kanıtı istediğinde servis depodan
okuyup istemciye aktarıyor. Kuyruktan kaldırılan 40.000 bayt, isteğe bağlı yolda iki kez
geçmeye devam ediyor.

**Vale anahtarı** (valet key), istemciye kaynağa doğrudan erişecek kadar dar ve kısa süreli bir
yetki verip veriyi servisin dışından akıtan yerleşimdir. Kimlik Doğrulama ve Yetkilendirme kursu imzalı bağlantıyı,
kapsamı ve süreli belirteci kurdu; doğrulama mekaniği burada tekrarlanmaz. Bu dersin ölçüleri
üçtür: servisin üzerinden **geçmeyen bayt**, açılan **yetki penceresi** ve kapsamı daraltmanın
**maliyeti**.

#### Baytın Servisten Çıkması

**DD12 — teslim kanıtının görüntülenme oranı 0,02.** Gerekçesi: kanıt yalnız itiraz ya da
denetim durumunda okunur, her gönderide değil. Duyarlılığı ölçüye zaten oran olarak giriyor.
**DD13 — kanıt aktarım havuzu 64 yuva** ve arıza senaryosu: **kanıt deposu yavaşlıyor**, yanıt
süresi 1 turdan 20 tura çıkıyor ve 80 tur sürüyor. Tur süresi bu kursun DD6 varsayımıdır (0,25
saniye), yani yavaşlama 20 saniye sürer. Sıklığı ayda 2 kez alınır.

Düzenek süreç içi bir modeldir: depo, ağ ve istemci yoktur; tur soyut bir adım, yuva bir sayaç,
bayt sayılan bir niceliktir.

```js
// vale/yol.mjs — kanit aktariminin iki yolunun surec ici modeli.
// Gercek depo, ag ve istemci yoktur: tur soyut bir adim, yuva bir sayac, bayt sayilir.

export const KANIT = 40_000, ANAHTAR = 512;   // DD8 kanit bayti; DD14 vale anahtari yaniti

// yol: "vekil" = bayt servisin uzerinden gecer; "vale" = servis yalniz anahtar uretir.
// Her tur: gelen aktarimlar yuva ister, depo suresi kadar yuvayi tutar, sonra birakir.
export function kos({ tur, gelen, havuz, normalSure, arizaSure, arizaBasi, arizaBitis, yol }) {
  const tutulan = [];
  const s = { kabul: 0, red: 0, tepeYuva: 0, servisBayt: 0, yuvaTur: 0, anahtar: 0 };
  let artik = 0;
  for (let t = 0; t < tur; t += 1) {
    for (let i = tutulan.length - 1; i >= 0; i -= 1) if (tutulan[i] <= t) tutulan.splice(i, 1);
    const sure = t >= arizaBasi && t < arizaBitis ? arizaSure : normalSure;
    artik += gelen;
    const n = Math.floor(artik);
    artik -= n;
    for (let i = 0; i < n; i += 1) {
      if (yol === "vale") { s.kabul += 1; s.anahtar += 1; s.servisBayt += ANAHTAR; continue; }
      if (tutulan.length >= havuz) { s.red += 1; continue; }
      tutulan.push(t + sure);
      s.kabul += 1; s.servisBayt += KANIT * 2;      // istemciden alinir, depoya yazilir
    }
    s.tepeYuva = Math.max(s.tepeYuva, tutulan.length);
    s.yuvaTur += tutulan.length;
  }
  return s;
}
```

```js
// vale/olc.mjs — kanit deposu yavasladiginda iki yolun tuttugu yuva ve dusen aktarim
import { kos, KANIT, ANAHTAR } from "./yol.mjs";

const V3 = 400_000, V8 = 3, GUN = 86_400;         // K01: gunluk gonderi, tepe carpani
const DD12 = 0.02;                                // kanitin goruntulenme orani
const TUR_S = 0.25, TUR = 320, HAVUZ = 64;        // DD6 tur suresi; DD13 havuz
const hizYukleme = (V3 / GUN) * V8, hizOkuma = ((V3 * DD12) / GUN) * V8;
const hiz = hizYukleme + hizOkuma;
const gelen = hiz * TUR_S;

console.log(`tepe kanit aktarimi ${hiz.toFixed(4)}/s (yukleme ${hizYukleme.toFixed(4)}, ` +
  `okuma ${hizOkuma.toFixed(4)}; DD12 = ${DD12})`);
console.log(`${TUR} tur x ${TUR_S} s = ${(TUR * TUR_S).toFixed(0)} s; tur basina ${gelen.toFixed(4)} aktarim`);
console.log(`DD13: depo yaniti 1 turdan 20 tura cikiyor, 80 tur (${(80 * TUR_S).toFixed(0)} s) suruyor`);

console.log(`\n${"yol".padEnd(8)}${"durum".padEnd(10)}${"kabul".padStart(8)}${"red".padStart(7)}` +
  `${"tepe yuva".padStart(11)}${"ort. yuva".padStart(11)}${"servis MB".padStart(12)}`);
for (const yol of ["vekil", "vale"])
  for (const [ad, arizaSure, arizaBasi, arizaBitis] of
    [["arizasiz", 1, TUR, TUR], ["arizali", 20, 80, 160]]) {
    const r = kos({ tur: TUR, gelen, havuz: HAVUZ, normalSure: 1,
      arizaSure, arizaBasi, arizaBitis, yol });
    console.log(`${yol.padEnd(8)}${ad.padEnd(10)}${String(r.kabul).padStart(8)}` +
      `${String(r.red).padStart(7)}${String(r.tepeYuva).padStart(11)}` +
      `${(r.yuvaTur / TUR).toFixed(2).padStart(11)}${(r.servisBayt / 1e6).toFixed(3).padStart(12)}`);
  }
console.log(`\nbir aktarimda servisten gecen bayt: vekil ${KANIT * 2}, vale ${ANAHTAR} ` +
  `(oran ${((KANIT * 2) / ANAHTAR).toFixed(1)} kat)`);
```

```
tepe kanit aktarimi 14.1667/s (yukleme 13.8889, okuma 0.2778; DD12 = 0.02)
320 tur x 0.25 s = 80 s; tur basina 3.5417 aktarim
DD13: depo yaniti 1 turdan 20 tura cikiyor, 80 tur (20 s) suruyor

yol     durum        kabul    red  tepe yuva  ort. yuva   servis MB
vekil   arizasiz      1133      0          4       3.54      90.640
vekil   arizali       1105     28         64      18.65      88.400
vale    arizasiz      1133      0          0       0.00       0.580
vale    arizali       1133      0          0       0.00       0.580

bir aktarimda servisten gecen bayt: vekil 80000, vale 512 (oran 156.3 kat)
```

Bu sayılar **ölçüm** sınıfındadır ve süreç içi bir modelden gelirler; girdileri K01'in hesabı ile
bu dersin varsayımlarıdır.

#### Yavaşlayan Deponun Servise Bulaşması

Arızasız satırlar iki yolun sessiz farkını veriyor: seksen saniyede vekil yol servisten 90,640
MB geçiriyor, vale yolu 0,580 MB. Aktarım başına 80.000 bayta karşı 512 bayt, 156,3 kat. Ortalama
tutulan yuva vekil yolda 3,54; bu, gelen hız ile hizmet süresinin çarpımıdır ve arızasız günde
64 yuvalık havuzun yanında küçüktür.

Arızalı satır asıl ayrımı yapıyor. Depo yanıt süresi yirmi kat uzayınca tutulan yuva ortalaması
18,65'e, tepe 64'e çıkıyor — havuz **doyuyor** — ve 28 aktarım reddediliyor. Kabul edilen aktarım
1133'ten 1105'e iniyor. Vale yolunda aynı yavaşlamada tutulan yuva 0, reddedilen 0, kabul 1133:
servis kanıtın baytına hiç dokunmadığı için deponun yavaşlaması servisin havuzuna yansımıyor.
İstemci hâlâ yavaş bir depoyla konuşur, ama bekleyen taraf istemcidir; **bulaşma kapsamı
servisin dışında kalır.** Havuzun doyması yalnız kanıt aktarımını değil, aynı havuzu paylaşan
başka işleri de etkiler; havuzların ayrılması bu kursun Arıza Yalıtımı konusundaki bölme
kalıbının sorusudur.

#### Kapsam ve Süre

Kalıbın karşılığı bir yetkidir ve yetki iki eksende ölçülür: ne kadar süre açık kaldığı ve kaç
nesneyi açtığı.

**DD14 — vale anahtarı süresi 300 saniye.** Gerekçesi: bir kanıt yüklemesi ya da görüntülemesi
tek bir kullanıcı eylemidir ve dakikalar sürmez; süre yeniden deneme payı bırakacak kadar uzun
tutulur. Duyarlılığı 60 ve 3600 saniyeyle verilir. **DD15 — bir anahtarın sızma olasılığı 10⁻⁶**;
anahtar günlük kaydına, tarayıcı geçmişine ya da paylaşılan bir bağlantıya düşebilir. İkisi de
varsayımdır.

```js
// vale/kapsam.mjs — kapsam daraltmanin anahtar uretimi, yetki penceresi ve maruz kalma etkisi
const V3 = 400_000, V8 = 3, V12 = 730, GUN = 86_400;   // K01: gonderi, tepe carpani, saklama
const SATICI = 4000, UC_TEPE = 513.89;                 // K01 hesabi: satici sayisi, uctaki tepe
const DD14 = 300, DD15 = 1e-6;                         // anahtar suresi (s), anahtar sizma olasiligi
const GUNLUK = V3 / SATICI;                            // satici basina gunluk gonderi = 100

// Kapsam: [ad, gunluk anahtar uretimi, bir anahtarin eristigi nesne sayisi]
const KAPSAM = [["tek nesne", V3, 1], ["satici-gun oneki", SATICI, GUNLUK],
  ["satici kovasi", SATICI, GUNLUK * V12]];

console.log(`DD14 anahtar suresi ${DD14} s, DD15 sizma olasiligi ${DD15}; ` +
  `gunde ${V3.toLocaleString("tr-TR")} kanit, ${SATICI} satici, satici basina ${GUNLUK} gonderi`);
console.log(`\n${"kapsam".padEnd(18)}${"anahtar/gun".padStart(13)}${"tepe anahtar/s".padStart(16)}` +
  `${"K01 ucunun".padStart(12)}${"acik pencere".padStart(14)}${"yuzey".padStart(9)}` +
  `${"nesne-saniye/gun".padStart(18)}`);
for (const [ad, uretim, yuzey] of KAPSAM) {
  const tepe = (uretim / GUN) * V8, acik = tepe * DD14;
  const maruz = uretim * DD15 * yuzey * DD14;
  console.log(`${ad.padEnd(18)}${uretim.toLocaleString("tr-TR").padStart(13)}` +
    `${tepe.toFixed(4).padStart(16)}${`%${((100 * tepe) / UC_TEPE).toFixed(3)}`.padStart(12)}` +
    `${acik.toFixed(1).padStart(14)}${yuzey.toLocaleString("tr-TR").padStart(9)}` +
    `${maruz.toFixed(1).padStart(18)}`);
}

console.log(`\n${"DD14 duyarliligi".padStart(17)}${"tek nesne acik".padStart(16)}` +
  `${"satici-gun acik".padStart(17)}${"kova nesne-saniye".padStart(19)}`);
for (const s of [60, 300, 3600]) {
  const t = (V3 / GUN) * V8 * s, g = (SATICI / GUN) * V8 * s;
  console.log(`${`${s} s`.padStart(17)}${t.toFixed(1).padStart(16)}${g.toFixed(1).padStart(17)}` +
    `${(SATICI * DD15 * GUNLUK * V12 * s).toFixed(0).padStart(19)}`);
}
const [t1, g1, k1] = KAPSAM.map(([, u, y]) => u * DD15 * y * DD14);
console.log(`\nkova -> satici-gun: maruz kalma ${(k1 / g1).toFixed(0)} kat azaliyor, ` +
  `anahtar uretimi degismiyor`);
console.log(`satici-gun -> tek nesne: maruz kalma ${(g1 / t1).toFixed(2)} kat degisiyor, ` +
  `anahtar uretimi ${(V3 / SATICI).toFixed(0)} kat artiyor`);
console.log(`en kotu durum ayni degil: sizan tek anahtarin actigi nesne ` +
  `${KAPSAM.map(([ad, , y]) => `${ad} ${y.toLocaleString("tr-TR")}`).join(", ")}`);
```

```
DD14 anahtar suresi 300 s, DD15 sizma olasiligi 0.000001; gunde 400.000 kanit, 4000 satici, satici basina 100 gonderi

kapsam              anahtar/gun  tepe anahtar/s  K01 ucunun  acik pencere    yuzey  nesne-saniye/gun
tek nesne               400.000         13.8889      %2.703        4166.7        1             120.0
satici-gun oneki          4.000          0.1389      %0.027          41.7      100             120.0
satici kovasi             4.000          0.1389      %0.027          41.7   73.000           87600.0

 DD14 duyarliligi  tek nesne acik  satici-gun acik  kova nesne-saniye
             60 s           833.3              8.3              17520
            300 s          4166.7             41.7              87600
           3600 s         50000.0            500.0            1051200

kova -> satici-gun: maruz kalma 730 kat azaliyor, anahtar uretimi degismiyor
satici-gun -> tek nesne: maruz kalma 1.00 kat degisiyor, anahtar uretimi 100 kat artiyor
en kotu durum ayni degil: sizan tek anahtarin actigi nesne tek nesne 1, satici-gun oneki 100, satici kovasi 73.000
```

#### Daraltmanın Getirisi Doğrusal Değil

Tablo, kapsamı daraltmanın iki basamağını ayırıyor ve basamaklar birbirine benzemiyor.

**Kova kapsamından satıcı-gün önekine inmek 730 kat kazandırıyor** ve hiçbir şeye mal olmuyor:
anahtar üretimi ikisinde de günde 4000, açık pencere ikisinde de 41,7 anahtar. Beklenen maruz
kalma 87.600 nesne-saniyeden 120,0'a düşüyor. Bu, bedava bir daraltmadır ve alınmaması için
gerekçe yoktur.

**Satıcı-gün önekinden tek nesneye inmek beklenen maruz kalmayı hiç değiştirmiyor** — iki satır
da 120,0 nesne-saniye — ama anahtar üretimini 100 kat artırıyor: günde 4000 yerine 400.000,
tepede 0,1389 yerine 13,8889 anahtar/s. Bu, K01'in uçtaki 513,89 istek/s'sinin yüzde 2,703'ü
eder. Beklenen değerin değişmemesinin nedeni aritmetiktir: kapsam yüz kat daralırken üretilen
anahtar sayısı yüz kat artıyor, çarpım sabit kalıyor.

Karar buna rağmen tek nesne lehine verilebilir, ama gerekçesi beklenen değer değildir: **en kötü
durum** eşit değil. Sızan tek bir anahtar tek nesne kapsamında 1, satıcı-gün önekinde 100, kova
kapsamında 73.000 nesne açar. Beklenen maruz kalma aynı olsa da dağılımın kuyruğu farklıdır ve
tek bir olayın taşıyabileceği en büyük zarar üç mertebe ayrılır.

Süre eksenine bakıldığında sonuç daha basit: açık pencere DD14 ile doğrusal büyür. Anahtar süresi
60 saniyeye çekildiğinde tek nesne kapsamında aynı anda geçerli anahtar 4166,7'den 833,3'e iner;
3600 saniyeye çıkarıldığında 50.000'e çıkar. Kova kapsamında bir saatlik anahtar günde 1.051.200
nesne-saniye üretir. **Süreyi kısaltmak her kapsamda doğrusal kazandırır; kapsamı daraltmak
yalnız ilk basamakta kazandırır.**

#### İki Günün Sayısı

**Arızasız günün bedeli iki kalemdir.** Servis, taşımadığı her bayt için bir anahtar üretir:
tek nesne kapsamında günde 400.000 imzalama, tepede 13,8889 istek/s, uçtaki hızın yüzde
2,703'ü. Ve kalıcı olarak açık bir yetki penceresi taşınır — tek nesne kapsamında 300 saniyelik
süreyle 4166,7 anahtar aynı anda geçerlidir. Vekil yolda böyle bir pencere yoktur; erişim isteğin
kendisiyle sınırlıdır.

**Arızalı günün kazancı yalıtımdır.** Kanıt deposu yirmi kat yavaşladığında vekil yol havuzunu
64 yuvada doyuruyor ve 80 saniyede 28 aktarım düşürüyor; vale yolunda düşen aktarım 0, tutulan
yuva 0. Fark bir hız farkı değil, bir bulaşma farkıdır: vekil yolda deponun arızası servisin
kaynağına dönüşür, vale yolunda istemcide kalır. Servisten geçmeyen bayt seksen saniyede 90,060
MB'dir (90,640 − 0,580) ve bu bayt, arızada tutulan yuvanın kaynağıdır.

#### Özet

- Aktarım başına servisten geçen bayt vekil yolda 80.000, vale yolunda 512; oran 156,3 kat, 80
  saniyelik koşumda 90,640 MB'ye karşı 0,580 MB.
- Depo 20 kat yavaşladığında vekil yolda tutulan yuva ortalaması 18,65, tepe 64 (havuz doyuyor)
  ve 28 aktarım düşüyor; vale yolunda yuva 0, düşen 0.
- Arızasız günün bedeli anahtar üretimidir: tek nesne kapsamında günde 400.000 imzalama, tepede
  13,8889 istek/s, K01'in uçtaki hızının yüzde 2,703'ü.
- Açık yetki penceresi süreyle doğrusaldır: DD14 = 60/300/3600 saniyede tek nesne kapsamında
  833,3 / 4166,7 / 50.000 anahtar aynı anda geçerlidir.
- Kapsam daraltmanın ilk basamağı bedava: kova → satıcı-gün beklenen maruz kalmayı 87.600'den
  120,0 nesne-saniyeye indiriyor, anahtar üretimini değiştirmiyor.
- İkinci basamak beklenen değeri değiştirmiyor (120,0 → 120,0) ama anahtar üretimini 100 kat
  artırıyor; gerekçesi en kötü durumdur — sızan bir anahtarın açtığı nesne 73.000 / 100 / 1.

#### Sonraki Adım

Kanıt yolu artık üç karara dayanıyor: yükün nerede duracağı, fişin ne zaman silineceği ve
anahtarın hangi kapsamla kaç saniye geçerli olacağı. Bu sayıların üçü de koda gömülü: yaşam
süresi bir sabit, anahtar süresi bir sabit, havuz boyu bir sabit. Bir arıza sırasında anahtar
süresini kısaltmak ya da kanıt yolunu tümden kapatmak gerekirse tek yol yeniden dağıtımdır ve
yeniden dağıtım kesinti bütçesinin planlı payından yer alır. Sonraki ders bu ayarların uygulamanın
dışına çıkarılmasını ele alır: değişikliğin bütün kopyalara yayılma süresi, önbellekli okumanın
bedeli, deponun kendisi düştüğünde davranış ve yanlış konan bir değerin bulaşma kapsamı.

### Dış Yapılandırma Deposu

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/dis-yapilandirma-deposu

Çalışma zamanı ayarlarının merkezileştirilmesi: bir değişikliğin üç kopyaya 25 saniyede yayılması, önbelleğin depo okumasını 5139 kat düşürmesi, yanlış bir değerin kademeli yaymada 61.668 yerine 20.556 hatalı yanıt üretmesi ve depo düştüğünde son bilinen değerle çalışmanın 40 saniyelik eşdeğer kesintiyi sıfıra indirmesi.

Önceki üç dersin kararları koda gömülü sayılarla duruyor: kanıtın yaşam süresi bir sabit,
anahtar süresi bir sabit, aktarım havuzunun boyu bir sabit, tekillik defterinin penceresi bir
sabit. Bir arıza sırasında anahtar süresini kısaltmak ya da kanıt yolunu tümden kapatmak
gerekirse tek yol yeniden dağıtımdır ve yeniden dağıtım K01'in aylık 43,2 dakikalık kesinti
bütçesindeki 15,0 dakikalık planlı paydan yer alır.

**Dış yapılandırma deposu** (external configuration store), çalışma zamanı ayarlarını uygulama
biriminin dışında tek bir yerde tutan ve kopyaların oradan okuduğu yerleşimdir. Backend kursu
yapılandırmanın şemayla tanımlanmasını, açılışta doğrulanmasını ve gizli değerin ayrılmasını
kurdu; burada o kurallar tekrarlanmaz. Bu dersin sorusu **çalışma zamanıdır**: bir değişiklik
kopyalara ne kadar sürede yayılır, önbellek deponun yükünü ne kadar düşürür, depo düştüğünde ne
olur ve yanlış konan bir değer kaç kopyaya bulaşır.

#### Yayılma ve Karışık Pencere

Düzenek süreç içi bir modeldir: gerçek depo, ağ ve kopya süreci yoktur; zaman modellenmiş
saniyelerle ilerler ve hiçbir sayı bu makinenin hızına bağlı değildir. Kopya sayısı ve kopya
başına istek hızı Uygulama Katmanı ve Servis Etkileşimi kursundaki Durumsuz Servisler dersinden
alınır: 3 kopya, kopya başına 171,30 istek/s.

**DD16 — yenileme aralığı 30 saniye.** Gerekçesi: bir ayarın yürürlüğe girmesi için beklenebilir
en uzun süre bir dakikanın altında tutulur. Duyarlılığı 5 ve 300 saniyeyle verilir.
**DD17 — yanlış bir değerin fark edilme süresi 120 saniye.** Gerekçesi: yanlış değer bir hata
oranı sıçraması olarak görünür ve doğrulanması zaman alır; farkın nasıl edileceği bu kursun
konusu değildir, Başarım Karşıt Kalıpları ve İzleme kursuna aittir.

```js
// yapilandirma/depo.mjs — dis yapilandirma deposunun ve kopya onbelleklerinin surec ici modeli.
// Gercek depo, ag ve kopya sureci yoktur; zaman modellenmis saniyelerle ilerler, sayaclar aciktir.

// yayma: "hepsine" = deger butun kopyalar icin gecerli; "kademeli" = once 0. kopya, dogrulanirsa otekiler
export function hedef(kopyaNo, t, { yayma, yanlisAn, farkEtme }) {
  const pencerede = t >= yanlisAn && t < yanlisAn + farkEtme;
  if (yayma === "kademeli") return kopyaNo === 0 && pencerede ? "yanlis" : "dogru";
  return pencerede ? "yanlis" : "dogru";
}

export function kos(a) {
  const { sure, kopya, aralik, kayma, hizKopya, dusAn, kalkAn, yenidenAn, diskOnbellek } = a;
  const deger = Array.from({ length: kopya }, () => "dogru");
  const ayakta = Array.from({ length: kopya }, () => true);
  const s = { hataliYanit: 0, dusenIstek: 0, depoOkuma: 0, basarisizOkuma: 0,
    ilkGorme: -1, sonGorme: -1, karisik: 0, yayilma: -1 };

  for (let t = 0; t < sure; t += 1) {
    if (t === yenidenAn)                         // devralma sonrasi bir kopya yeniden basliyor
      ayakta[kopya - 1] = diskOnbellek || !(t >= dusAn && t < kalkAn);
    if (t >= kalkAn && !ayakta[kopya - 1]) ayakta[kopya - 1] = true;
    for (let k = 0; k < kopya; k += 1) {
      if (t >= k * kayma && (t - k * kayma) % aralik === 0) {
        s.depoOkuma += 1;
        if (t >= dusAn && t < kalkAn) s.basarisizOkuma += 1;   // son bilinen deger korunur
        else deger[k] = hedef(k, t, a);
      }
      if (!ayakta[k]) { s.dusenIstek += hizKopya; continue; }
      if (deger[k] === "yanlis") s.hataliYanit += hizKopya;
    }
    const n = deger.filter((d) => d === "yanlis").length;
    const beklenen = deger.map((_, k) => hedef(k, t, a)).filter((d) => d === "yanlis").length;
    if (n > 0 && s.ilkGorme < 0) s.ilkGorme = t;
    if (n > 0) s.sonGorme = t;
    if (n > 0 && n < kopya) s.karisik += 1;
    if (s.yayilma < 0 && beklenen > 0 && n === beklenen) s.yayilma = t - a.yanlisAn;
  }
  return s;
}
```

```js
// yapilandirma/olc.mjs — yanlis bir degerin bulasma kapsami ve deponun dusmesindeki davranis
import { kos } from "./depo.mjs";

const KOPYA = 3, HIZ_KOPYA = 171.30;             // M19/K03: 3 kopya, kopya basina 171,30 istek/s
const UC_TEPE = 513.89, BUTCE = 28.2 * 60;       // K01: uctaki tepe istek/s, aylik ariza payi
const ARALIK = 30, FARK = 120, SURE = 600;       // DD16 yenileme araligi, DD17 fark etme suresi
const TABAN = { sure: SURE, kopya: KOPYA, aralik: ARALIK, hizKopya: HIZ_KOPYA, yanlisAn: 65,
  farkEtme: FARK, dusAn: SURE, kalkAn: SURE, yenidenAn: -1, diskOnbellek: true };

console.log(`${KOPYA} kopya, kopya basina ${HIZ_KOPYA} istek/s (M19/K03), uctaki tepe ${UC_TEPE}`);
console.log(`DD16 yenileme araligi ${ARALIK} s, DD17 fark edilme suresi ${FARK} s; ` +
  `yanlis deger 65. saniyede yaziliyor`);
console.log(`\n${"yayma".padEnd(10)}${"kayma".padStart(7)}${"yayilma".padStart(9)}` +
  `${"ilk gorme".padStart(11)}${"son gorme".padStart(11)}${"karisik s".padStart(11)}` +
  `${"hatali yanit".padStart(14)}${"bulasan kopya".padStart(15)}`);
for (const yayma of ["hepsine", "kademeli"])
  for (const kayma of [0, 10]) {
    const r = kos({ ...TABAN, yayma, kayma });
    console.log(`${yayma.padEnd(10)}${String(kayma).padStart(7)}${String(r.yayilma).padStart(9)}` +
      `${String(r.ilkGorme).padStart(11)}${String(r.sonGorme).padStart(11)}` +
      `${String(r.karisik).padStart(11)}${r.hataliYanit.toFixed(0).padStart(14)}` +
      `${String(yayma === "hepsine" ? KOPYA : 1).padStart(15)}`);
  }

// Depo dusmesi: 200. saniyede dusuyor, 180 s kapali; 260. saniyede bir kopya yeniden basliyor.
console.log(`\ndepo dusmesi: 180 s kapali; 260. saniyede bir kopya devralma sonrasi yeniden basliyor`);
console.log(`${"davranis".padEnd(24)}${"basarisiz okuma".padStart(17)}${"dusen istek".padStart(13)}` +
  `${"esdeger kesinti s".padStart(19)}${"ariza payinin".padStart(15)}`);
for (const [ad, diskOnbellek] of [["son bilinen degerle", true], ["depo zorunlu", false]]) {
  const r = kos({ ...TABAN, yayma: "hepsine", kayma: 10, yanlisAn: SURE,
    dusAn: 200, kalkAn: 380, yenidenAn: 260, diskOnbellek });
  const kesinti = r.dusenIstek / UC_TEPE;        // uctaki tepe hiza gore esdeger kesinti saniyesi
  console.log(`${ad.padEnd(24)}${String(r.basarisizOkuma).padStart(17)}` +
    `${r.dusenIstek.toFixed(0).padStart(13)}${kesinti.toFixed(2).padStart(19)}` +
    `${`%${((100 * kesinti) / BUTCE).toFixed(2)}`.padStart(15)}`);
}

console.log(`\n${"DD16".padStart(8)}${"depo okuma/s".padStart(14)}${"en kotu yayilma".padStart(17)}` +
  `${"hatali yanit ust siniri".padStart(25)}`);
for (const a of [5, 30, 300])
  console.log(`${`${a} s`.padStart(8)}${(KOPYA / a).toFixed(4).padStart(14)}` +
    `${`${a} s`.padStart(17)}${(UC_TEPE * (FARK + a)).toFixed(0).padStart(25)}`);
console.log(`her istekte okunsaydi depo okuma ${UC_TEPE}/s; DD16 = ${ARALIK} s ile ` +
  `${(UC_TEPE / (KOPYA / ARALIK)).toFixed(0)} kat az`);
```

```
3 kopya, kopya basina 171.3 istek/s (M19/K03), uctaki tepe 513.89
DD16 yenileme araligi 30 s, DD17 fark edilme suresi 120 s; yanlis deger 65. saniyede yaziliyor

yayma       kayma  yayilma  ilk gorme  son gorme  karisik s  hatali yanit  bulasan kopya
hepsine         0       25         90        209          0         61668              3
hepsine        10       25         70        209         40         61668              3
kademeli        0       25         90        209        120         20556              1
kademeli       10       25         90        209        120         20556              1

depo dusmesi: 180 s kapali; 260. saniyede bir kopya devralma sonrasi yeniden basliyor
davranis                  basarisiz okuma  dusen istek  esdeger kesinti s  ariza payinin
son bilinen degerle                    18            0               0.00          %0.00
depo zorunlu                           18        20556              40.00          %2.36

    DD16  depo okuma/s  en kotu yayilma  hatali yanit ust siniri
     5 s        0.6000              5 s                    64236
    30 s        0.1000             30 s                    77084
   300 s        0.0100            300 s                   215834
her istekte okunsaydi depo okuma 513.89/s; DD16 = 30 s ile 5139 kat az
```

Bu sayılar **ölçüm** sınıfındadır ama zaman ekseni modellenmiş saniyedir; koşum aritmetiktir ve
ortama bağlı değildir.

#### Yayılma Bir Pencere Açar

Değişiklik 65. saniyede depoya yazılıyor, kopyalar 25 saniye sonra tamamlanmış oluyor. Yayılma
süresi yenileme aralığından küçük olabilir — yazma anı ile bir sonraki yenileme arasındaki
mesafeye bağlıdır — ama üst sınırı aralıktır. Alt tablonun son sütunu bunu doğruluyor: DD16 = 5,
30, 300 saniyede en kötü yayılma sırasıyla 5, 30, 300 saniyedir.

İkinci satır kaymanın ne yapıp ne yapmadığını gösteriyor. Kopyaların yenilemesi 10 saniyelik
kaymayla dağıtıldığında ilk gören kopya 90 yerine 70. saniyede görüyor ve **40 saniyelik karışık
pencere** açılıyor: kopyaların bir kısmı yeni, bir kısmı eski değerle yanıt veriyor. Toplam hatalı
yanıt ise iki satırda da 61.668; kayma yayılmayı hızlandırmıyor, yalnız zamana yayıyor.

Karışık pencere bir kusur olarak okunmamalı. İstemcinin bir isteği yeni değerle, hemen ardından
gelen isteği eski değerle karşılanabilir; bir yapılandırma değişikliği **atomik değildir** ve
değerlerin yan yana anlamlı olması gerekir. Birbirine bağımlı iki ayar tek tek yazılırsa karışık
pencerede geçersiz bir bileşim oluşur; bu yüzden bağımlı ayarlar tek bir kayıt olarak yazılır.

#### Bulaşma Kapsamı ve Deponun Düşmesi

Üçüncü ve dördüncü satırlar yanlış bir değerin kapsamını ölçüyor. Değer bütün kopyalar için
geçerli yazıldığında üç kopyaya birden bulaşıyor ve DD17 = 120 saniyelik fark etme penceresinde
**61.668 hatalı yanıt** üretiyor. Aynı değer önce tek bir kopyaya işaretlenip doğrulandıktan
sonra ötekilere verildiğinde bulaşan kopya 1'de kalıyor ve hatalı yanıt **20.556** oluyor, yani
tam üçte biri. Kademeli yaymanın karışık penceresi 120 saniyedir ve bu, kusur değil kalıbın
kendisidir: iki değerin bir arada yaşadığı süre, farkın edilebilmesi için ayrılmış süredir.

Alt tabloda depo düşüyor: 180 saniye kapalı kalıyor ve bu sırada bir kopya devralma sonrası
yeniden başlıyor. İki davranış ayrılıyor. **Son bilinen değerle çalışma** seçildiğinde 18
başarısız okuma oluyor, kopyalar önbellekteki değeri sürdürüyor, yeniden başlayan kopya değeri
diskteki kopyasından yüklüyor ve düşen istek 0. **Depo zorunlu** seçildiğinde aynı 18 başarısız
okuma oluyor ama yeniden başlayan kopya açılamıyor: 120 saniye boyunca 20.556 istek düşüyor. Bu,
uçtaki tepe hıza göre 40,00 saniyelik eşdeğer kesintidir ve K01'in aylık 28,2 dakikalık arıza
payının yüzde 2,36'sını tek bir olayda harcar.

Sonuç bir tasarım kuralıdır: **dış yapılandırma deposu, kendisi düştüğünde uygulamayı düşürmeyecek
biçimde okunmalıdır.** Aksi halde tek bir yardımcı bileşen, bağımlı olduğu bütün servislerin
hizmet erişilebilirliğine üst sınır koyar. Açılışta doğrulama kuralı bununla çelişmez; doğrulama
son bilinen değer üzerinde yapılır, eksik olan depo değil değerdir.

#### İki Günün Sayısı

**Arızasız günün bedeli üç kalemdir.** Birincisi depo okumasıdır ve önbellek onu küçük tutar:
DD16 = 30 saniye ile üç kopya saniyede 0,1000 okuma yapar. Her istekte okunsaydı 513,89 okuma/s
olurdu — 5139 kat. İkincisi gecikmedir: bir ayar değişikliği anında yürürlüğe girmez, en kötü
durumda DD16 kadar bekler. Üçüncüsü karışık penceredir; kopyalar bir süre farklı değerlerle
çalışır ve bu, bağımlı ayarların tek kayıtta tutulmasını zorunlu kılar.

DD16 bu üç kalemi birbirine bağlar ve iki yönlü çeker. Aralık 5 saniyeye indirilirse depo
okuması 0,6000/s'ye çıkar (altı kat) ama hatalı yanıtın üst sınırı 77.084'ten 64.236'ya iner.
Aralık 300 saniyeye çıkarılırsa okuma 0,0100/s'ye düşer ve üst sınır 215.834'e çıkar. **Yenileme
aralığı bir başarım parametresi değil, bir geri alma süresidir**: yanlış bir değerin ne kadar
süre yürürlükte kalacağını belirler.

**Arızalı günün kazancı iki kalemdir.** Depo düştüğünde son bilinen değerle çalışma düşen isteği
20.556'dan 0'a, eşdeğer kesintiyi 40,00 saniyeden sıfıra indirir; aylık arıza payının yüzde
2,36'sı korunur. Ve yanlış bir değerin bulaşma kapsamı kademeli yaymayla üç kopyadan bire,
hatalı yanıt 61.668'den 20.556'ya iner. İkisi de arızasız günde hiçbir şey iyileştirmez; birincisi
bir okuma yolu, ikincisi bir yayma prosedürü ekler.

#### Özet

- Bir değişiklik üç kopyaya 25 saniyede yayıldı; üst sınır yenileme aralığıdır ve DD16 = 5/30/300
  saniyede sırasıyla 5, 30, 300 saniyedir.
- Yenilemeyi kaydırmak yayılmayı hızlandırmıyor, 40 saniyelik karışık pencere açıyor; toplam
  hatalı yanıt iki durumda da 61.668. Bağımlı ayarlar bu yüzden tek kayıtta yazılır.
- Önbellekli okuma depo yükünü 0,1000 okuma/s'de tutuyor; her istekte okunsaydı 513,89 olurdu,
  5139 kat.
- Kademeli yayma bulaşan kopyayı 3'ten 1'e, hatalı yanıtı 61.668'den 20.556'ya indiriyor;
  karşılığında 120 saniyelik karışık pencereyi kalıcı kılıyor.
- Depo düştüğünde son bilinen değerle çalışma düşen isteği 20.556'dan 0'a indiriyor: 40,00
  saniyelik eşdeğer kesinti, K01'in aylık 28,2 dakikalık arıza payının yüzde 2,36'sı.
- DD16 bir başarım parametresi değil geri alma süresidir: 5 saniyede hatalı yanıt üst sınırı
  64.236, 300 saniyede 215.834.

#### Sonraki Adım

Bu konudaki beş kalıp aynı sistemin içinde çalıştı. Tekillik defteri, telafi zinciri, talep fişi,
vale anahtarı ve dış yapılandırma deposu — hepsi **yeni** düzenin parçaları ve hepsi K01'in
sayılarına oturuyor. Fakat gönderi takip ve ücretlendirme servisi sıfırdan doğmadı: eski sistem
hâlâ ayakta, aynı takip numaralarını yanıtlıyor, aynı fatura satırlarını üretiyor ve yeni düzenin
yanında duruyor. Beş kursun tasarladığı hiçbir şey o sistemin nasıl devralınacağını söylemedi —
hangi yolun ne zaman taşınacağı, taşınmamış yolların nereye gideceği, iki sistemde birden tutulan
durumun nasıl tutarlı kalacağı ve geçişin ne kadar süreceği hiç sorulmadı. Sonraki ders eski
sistemin aşamalı olarak değiştirilmesini ele alır.

### Boğucu İncir Geçişi

Source: https://academia.sh/tr/kurslar/dayaniklilik-kaliplari/bogucu-incir-gecisi

Eski sistemin yol yol değiştirilmesi: sekiz yolun iki farklı sırayla taşınması, hacim sırasının trafiği 3,89 kat hızlı taşıyıp çift yazma yükünü 1,52 kat büyütmesi, geçiş cephesinin zaman aşımı bütçesinden pay alması ve geri alınabilirliğin çift yazma kesildiği anda bir turdan 3360 saniyeye çıkması.

Önceki beş ders yeni düzenin parçalarını kurdu: tekillik defteri, telafi zinciri, talep fişi, vale
anahtarı ve dış yapılandırma deposu. Hepsi tek bir varsayımın üstünde duruyor — gönderi takip ve
ücretlendirme servisinin bu tasarımdan ibaret olduğu. Oysa servis sıfırdan doğmadı: eski sistem
hâlâ ayakta ve yeni düzenin yanında duruyor.

**Boğucu incir geçişi** (strangler fig), eski sistemi bir kerede değiştirmek yerine yollarını tek
tek taşıyan ve ikisinin önüne bir yönlendirme katmanı koyan geçiş biçimidir. O katman **geçiş
cephesi**dir: her isteği alır, o yolun taşınıp taşınmadığına bakar ve eski ya da yeni sisteme
gönderir. Ölçüler dörttür: taşınan yol sayısı ve sırası, iki sistemde birden tutulan durumun
büyüklüğü, cephenin arızasız gündeki bedeli ve bir yolu geri çevirmenin turu.

#### Sıra Bir Durum Kararıdır

Servisin sekiz yolu ve beş durum varlığı vardır. Bir yol taşındığında, dokunduğu bir durum varlığı
taşınmamış yollar tarafından da kullanılıyorsa o varlık **bölünür**: iki depoda birden tutulmak ve
her yazmada ikisine birden yazılmak zorundadır. Bölünmüş durum geçişin asıl maliyetidir ve taşıma
sırası onu doğrudan belirler.

**DD18 — satıcı başına günde bir fatura okuması**, yani günde 4000; gerekçesi K01'in 4000
satıcısıdır. Tarife hacmi Veri Katmanı Ölçekleme kursunun D5 varsayımından, kanıt hacimleri bu
konunun DD8 ve DD12 varsayımlarından gelir; kalanı K01'in hesabıdır.

```js
// incir/gecis.mjs — yol yol tasimanin surec ici modeli. Gercek sistem, ag ve depo yoktur:
// yollar ve durum varliklari birer nesne, bolunmus durum bir kume islemidir.

// [yol adi, gunluk istek hacmi (K01 hesaplari ve DD18), okudugu durum, yazdigi durum]
export const YOL = [
  ["takip-sorgu", 12_000_000, "gonderi olay", ""],
  ["durum-olayi", 2_800_000, "gonderi", "olay"],
  ["gonderi-olustur", 400_000, "", "gonderi"],
  ["kanit-yukleme", 400_000, "olay", "kanit"],
  ["kanit-okuma", 8_000, "kanit", ""],
  ["ucret-donem", 4_000, "gonderi olay tarife", "fatura"],
  ["fatura-okuma", 4_000, "fatura", ""],
  ["tarife-yonetim", 1, "", "tarife"],
].map(([ad, hacim, o, y]) => ({ ad, hacim, dokunur: `${o} ${y}`.split(" ").filter(Boolean) }));

// Durum varliginin gunluk yazma hacmi (K01 hesaplari; tarife M19/K04'un D5 varsayimi)
export const YAZMA = { gonderi: 400_000, olay: 2_800_000, kanit: 400_000, fatura: 4_000, tarife: 1 };
export const GUN = 86_400;

// Tasinmis yol kumesi verildiginde bolunmus durum varliklari ve cift yazma hizi
export function bolunmus(tasinan) {
  const ad = new Set(tasinan.map((y) => y.ad)), kalan = YOL.filter((y) => !ad.has(y.ad));
  const b = Object.keys(YAZMA).filter((d) => tasinan.some((y) => y.dokunur.includes(d)) && kalan.some((y) => y.dokunur.includes(d)));
  return { varlik: b, ciftYazma: b.reduce((t, d) => t + YAZMA[d], 0) / GUN };
}

// Sira: "hacim" = en cok istek alan yol once; "durum" = bolunmus yazmayi en aza indiren yol once
export function sirala(kip) {
  if (kip === "hacim") return [...YOL].sort((a, b) => b.hacim - a.hacim);
  const kalan = [...YOL], sira = [];
  while (kalan.length > 0) {
    let en = 0;
    for (let i = 1; i < kalan.length; i += 1) {
      const a = bolunmus([...sira, kalan[i]]).ciftYazma, e = bolunmus([...sira, kalan[en]]).ciftYazma;
      if (a < e || (a === e && kalan[i].hacim > kalan[en].hacim)) en = i;
    }
    sira.push(...kalan.splice(en, 1));
  }
  return sira;
}
```

```js
// incir/olc.mjs — iki tasima sirasinin cift yazma yuku, tasinan trafik, geri alma ve arizali gun
import { YOL, YAZMA, GUN, bolunmus, sirala } from "./gecis.mjs";

const TOPLAM = YOL.reduce((t, y) => t + y.hacim, 0);
const UC_TEPE = 513.89, TARAMA = 833.33, BUTCE = 28.2 * 60;   // K01 hesaplari; aylik ariza payi
console.log(`${YOL.length} yol, ${Object.keys(YAZMA).length} durum varligi, ` +
  `gunluk ${TOPLAM.toLocaleString("tr-TR")} istek`);

const izle = (kip) => {
  const tasinan = [], satir = [];
  let ciftAlan = 0, trafikAlan = 0;
  for (const y of sirala(kip)) {
    tasinan.push(y);
    const b = bolunmus(tasinan), pay = tasinan.reduce((t, x) => t + x.hacim, 0) / TOPLAM;
    ciftAlan += b.ciftYazma; trafikAlan += pay;
    satir.push([y.ad, pay, b.varlik.length, b.ciftYazma]);
  }
  return { satir, ciftAlan, trafikAlan };
};

const R = {};
for (const kip of ["hacim", "durum"]) {
  R[kip] = izle(kip);
  console.log(`\n${kip} sirasi`);
  console.log(`${"adim".padStart(5)}${"tasinan yol".padStart(21)}${"tasinan trafik".padStart(16)}${"bolunmus varlik".padStart(17)}${"cift yazma/s".padStart(14)}`);
  R[kip].satir.forEach(([ad, pay, n, c], i) => console.log(`${String(i + 1).padStart(5)}${ad.padStart(21)}${`%${(100 * pay).toFixed(2)}`.padStart(16)}${String(n).padStart(17)}${c.toFixed(2).padStart(14)}`));
  console.log(`cift yazma alani ${R[kip].ciftAlan.toFixed(2)} yazma/s-adim, tasinan trafik alani ${R[kip].trafikAlan.toFixed(4)} adim`);
}
console.log(`\nhacim / durum: cift yazma ${(R.hacim.ciftAlan / R.durum.ciftAlan).toFixed(2)} kat, tasinan trafik ${(R.hacim.trafikAlan / R.durum.trafikAlan).toFixed(2)} kat`);

// Geri alma: cift yazma surerken yonlendirme degisimi 1 tur; kesildikten sonra geri doldurma gerekir.
console.log(`\n${"cift yazma kesildikten sonra".padEnd(28)}${"geri doldurulacak olay".padStart(24)}${"geri alma s".padStart(13)}${"ariza payinin".padStart(15)}`);
for (const [ad, sn] of [["0 (cift yazma suruyor)", 0], ["1 saat", 3600], ["1 gun", 86_400]]) {
  const kayit = (YAZMA.olay / GUN) * sn, s = kayit / TARAMA;
  console.log(`${ad.padEnd(28)}${Math.round(kayit).toLocaleString("tr-TR").padStart(24)}${s.toFixed(2).padStart(13)}${`%${((100 * s) / BUTCE).toFixed(2)}`.padStart(15)}`);
}

// Arizali gun: her sirada tasinan trafik yuzde 50'yi ilk gectigi adimda yeni sistem duruyor.
const DD20 = 60;                                  // cephesiz yerlesimde yonlendirme yasam suresi, s
console.log(`\n${"sira".padEnd(8)}${"adim".padStart(6)}${"tasinan trafik".padStart(16)}${"cephe: dusen".padStart(14)}${"DD20: dusen".padStart(13)}${"esdeger kesinti s".padStart(19)}${"ariza payinin".padStart(15)}`);
for (const kip of ["hacim", "durum"]) {
  const i = R[kip].satir.findIndex(([, p]) => p >= 0.5), pay = R[kip].satir[i][1];
  const d = UC_TEPE * pay * DD20;
  console.log(`${kip.padEnd(8)}${String(i + 1).padStart(6)}${`%${(100 * pay).toFixed(2)}`.padStart(16)}${(UC_TEPE * pay).toFixed(0).padStart(14)}${d.toFixed(0).padStart(13)}${(d / UC_TEPE).toFixed(2).padStart(19)}${`%${((100 * d) / UC_TEPE / BUTCE).toFixed(2)}`.padStart(15)}`);
}
```

```
8 yol, 5 durum varligi, gunluk 15.616.001 istek

hacim sirasi
 adim          tasinan yol  tasinan trafik  bolunmus varlik  cift yazma/s
    1          takip-sorgu          %76.84                2         37.04
    2          durum-olayi          %94.77                2         37.04
    3      gonderi-olustur          %97.34                2         37.04
    4        kanit-yukleme          %99.90                3         41.67
    5          kanit-okuma          %99.95                2         37.04
    6          ucret-donem          %99.97                2          0.05
    7         fatura-okuma         %100.00                1          0.00
    8       tarife-yonetim         %100.00                0          0.00
cift yazma alani 189.86 yazma/s-adim, tasinan trafik alani 7.6878 adim

durum sirasi
 adim          tasinan yol  tasinan trafik  bolunmus varlik  cift yazma/s
    1       tarife-yonetim           %0.00                1          0.00
    2         fatura-okuma           %0.03                2          0.05
    3      gonderi-olustur           %2.59                3          4.68
    4          kanit-okuma           %2.64                4          9.31
    5        kanit-yukleme           %5.20                4         37.08
    6          ucret-donem           %5.23                2         37.04
    7          takip-sorgu          %82.07                2         37.04
    8          durum-olayi         %100.00                0          0.00
cift yazma alani 125.19 yazma/s-adim, tasinan trafik alani 1.9775 adim

hacim / durum: cift yazma 1.52 kat, tasinan trafik 3.89 kat

cift yazma kesildikten sonra  geri doldurulacak olay  geri alma s  ariza payinin
0 (cift yazma suruyor)                             0         0.00          %0.00
1 saat                                       116.667       140.00          %8.27
1 gun                                      2.800.000      3360.01        %198.58

sira      adim  tasinan trafik  cephe: dusen  DD20: dusen  esdeger kesinti s  ariza payinin
hacim        1          %76.84           395        23694              46.11          %2.72
durum        7          %82.07           422        25305              49.24          %2.91
```

Bu sayılar **ölçüm** sınıfındadır; süreç içi bir modelden gelirler ve girdileri K01'in hesapları
ile bu konunun varsayımlarıdır.

#### İki Sıra, İki Ayrı Şey İyileştiriyor

Hacim sırası ilk adımda trafiğin yüzde 76,84'ünü taşıyor. Bedeli hemen başlıyor: `gonderi` ve
`olay` ilk adımdan itibaren bölünüyor ve
çift yazma geçiş boyunca 37,04 yazma/s'de kalıyor. Bu ortalama bir hızdır ve bölünmüş varlıkların
yazması ikinci depoya **yeniden** uygulandığı için yazma yolunu 74,08 yazma/s'ye, tam iki katına
çıkarır.

Durum sırası tersini yapıyor: ilk altı adımda çift yazma neredeyse yok, ama taşınan trafik yüzde
5,23'te kalıyor ve eski sistem geçişin büyük bölümünde yükünün tamamını taşıyor. İki integral
ödünleşimi tek satırda veriyor — hacim sırası trafiği 3,89 kat hızlı taşıyor, çift yazma yükünü
1,52 kat büyütüyor.

Bölünmüş varlık sayısı üçüncü bir ayrım açıyor: durum sırası çift yazma **hızını** düşürürken
bölünmüş varlık **sayısını** 4'e çıkarıyor (hacim sırasında en fazla 3) — daha çok kod yolu, daha
az bayt. **Geçiş sırasının tek bir en iyisi yoktur**; seçim, eski sistemin yükü mü çift yazmanın
riski mi daha pahalı sorusuna verilen yanıttır.

#### Cephenin Bedeli ve Geri Alınabilirlik

Cephe bütün trafiğin önünde durur ve arızasız gündeki bedeli üç kalemdir. Birincisi bir **ek
duraktır**: günde 15.616.001 isteğin tamamı, tepe uçta 513,89 istek/s, fazladan bir yönlendirme
kararından geçer. İkincisi **zaman aşımı bütçesindeki paydır**. Zaman Aşımı Bütçeleri dersi 200
milisaniyelik eşiği bölüştürmüştü: ağ geçidi payı 20 ms, kola kalan 180 ms, dağıtım 90/90. Cephe
de ağ geçidi kadar pay alırsa (**DD19**) kola kalan 160 ms'ye iner ve dağıtım 80/80 olur — her
adımın payı yüzde 11,1 daralır. Üçüncüsü çift yazmadır. Cephe ayrıca yeni bir tekil noktadır:
Dağıtım Damgaları dersi yönlendirme eşlemesinin bulaşma kapsamını yüzde 90,9 ölçmüştü, cephenin
kapsamı yüzde 100'dür.

Karşılığında aldığı şey **geri alınabilirliktir**. Alt tablo geçişin ortasında yeni sistemin
durduğu durumu sayıyor. Cephe varken bir yolu geri çevirmek bir yönlendirme kararının
değişmesidir: hacim sırasında 395, durum sırasında 422 istek düşer. İstemcilerin doğrudan
yönlendirildiği bir yerleşimde geri çevirme yönlendirme kaydının yaşam süresi kadar sürer
(**DD20 — 60 saniye**) ve düşen istek 23.694 ile 25.305'e çıkar: 46–49 saniyelik eşdeğer kesinti,
K01'in aylık arıza payının yüzde 2,72–2,91'i.

Geri alınabilirliğin bir son kullanma tarihi var. Çift yazma sürerken eski sistemin verisi
günceldir ve geri alma bir turdur. Kesildikten bir saat sonra eski sisteme 116.667 olay geri
doldurulmalıdır: K01'in 833,33 kayıt/s tarama hızıyla 140,00 saniye, arıza payının yüzde 8,27'si.
Bir gün sonra 2.800.000 olay ve 3360,01 saniye — payın yüzde 198,58'i. **Çift yazmanın kesilmesi
bir tasarruf kararı değil, geri dönüşün kapatılmasıdır.**

#### Özet

- Taşınan bir yolun dokunduğu durum varlığı taşınmamış bir yol tarafından da kullanılıyorsa
  bölünür ve iki depoya birden yazılır; çift yazma yazma yolunu 37,04'ten 74,08 yazma/s'ye çıkarır.
- Hacim sırası ilk adımda trafiğin yüzde 76,84'ünü taşıyor ama çift yazmayı hemen 37,04 yazma/s'ye
  çıkarıyor; durum sırası ilk altı adımı çift yazmasız geçiriyor, trafiği yüzde 5,23'te tutuyor.
- İki integral ödünleşimi veriyor: hacim sırası trafiği 3,89 kat hızlı taşıyor, çift yazma yükünü
  1,52 kat büyütüyor. Tek bir en iyi sıra yoktur.
- Cephenin arızasız gündeki bedeli: günde 15.616.001 isteğe bir ek durak, bütçeden ağ geçidi kadar
  pay (kol payı 180 → 160 ms, dağıtım 90/90 → 80/80) ve yüzde 100 bulaşma kapsamlı tekil nokta.
- Cephenin arızalı gündeki kazancı geri çevirme hızıdır: düşen istek 25.305 yerine 422.
- Geri alma ancak çift yazma sürerken bir turdur; kesildikten bir gün sonra 3360,01 saniyeye
  (arıza payının yüzde 198,58'i) çıkar.

#### Kurs Kapanışı

Kurs, dört kursun tasarladığı sistemi arıza altında ele aldı ve her derste aynı iki soruyu sordu:
bu kalıp arızasız günde neye mal oluyor, arızalı günde neyi kaç birim kurtarıyor.

| Ders | Arıza kipi | Arızasız günün bedeli | Arızalı günün kazancı |
|---|---|---|---|
| Arıza Kipleri | durma, yavaşlama, kısmi arıza, bayat içerik, ağ bölünmesi | yanıta 8 bayt damga (4111,12 bayt/s); adlandırma için 20 çağrılık pencere | durma 97,22 istek/s ve 1 bileşen, yavaşlama 513,89 istek/s ve 2 bileşen — 5,29 kat |
| Devre Kesici | bağımlılığın yavaşlaması ve durması | 1166 çağrıda denetim, bağımlılık başına 20 kayıt; 0,10 eşiği sağlıklı günde 386 geçerli olayı reddediyor | yuvasız takip isteği 671 → 0; olay bacağının yuva-turu 19.312 → 1646 (%91,48) |
| Bölme Kalıbı | bir bağımlılığın yavaşlaması | düşen istek 105 → 578 (5,5 kat), doluluk 0,541 → 0,524; 4239 kez komşuda boş yuva varken red | komşu akışta düşen istek 2654 → 172 (%93,5), algılamaya bağlı değil |
| Yeniden Deneme ve Fırtına Riski | tam kesinti ve kısmi bozulma | izin 1 → 27'de çağrı değişmiyor, çarpan 1,03 | deneme bütçesi 0,30 fırtınayı 6,24 → 2,88 çağrı/tura indiriyor; bedeli 103 düşen istek |
| Zaman Aşımı Bütçeleri | bağımlılığın yavaşlaması (AY10) | son tarih alanı 40 bayt (yanıtın %8,3'ü); 48 isteğin 2'si kesiliyor | ağırlıklı dağıtım ortancayı 200 → 93 ms, tutulan yuvayı 82,4 → 40,2 (iptal sinyaliyle) |
| Geri Basınç | aşırı yük (AY11) | 4164 geçerli olay reddi (%3,57), saniyede 291,66 sinyal denetimi | 44.399 olay kayıptan redde dönüyor; dar açıkta kayıp 34.064 → 8579 (3,971 kat) |
| Kısıtlama ve Yük Boşaltma | toplu iş tepeye taşıyor (AY13a); uç düğümü düşüyor (AY13b) | kısıtlama 15.630 geçerli sorguyu reddediyor (%6,25); boşaltmanın bedeli yok | boşaltma AY13b'de tepenin 0,9348'ini koruyor; kapısız düzen arıza payının %56,7'sini yerdi |
| Zarif Bozulma | isteğe bağlı bağımlılık (AY14a); çekirdek (AY14b) düştü | 24 baytlık tazelik göstergesi (%5,0), 2,29 MiB yedek defteri, 1666,68 yazma/s | AY14a'da kesinti 15,00 → 0,00 dakika; AY14b'de yalnız 15,00 → 14,02 |
| Devralma Tasarımı | etkin kopyanın durması | eşik 1'de ayda 120 s yanlış devralma; eşik 3'te sıfır, geçiş penceresi 4 → 8 s | kesinti 20,0 dakikadan 16 saniyeye (75 kat); arıza payının %70,9'u yerine %0,95'i |
| Sağlık Ucu İzleme | yarı düşmüş kopya; paylaşılan bağımlılığın düşmesi | derin denetim depoya %1,08 yük (48 kopyada %17,28); yanlış çıkarma ayda 13,3 kez yükü 1,50 katına | sessiz kayıp 17 → 0; hazır olma denetimi 40 okuma ve 10 yazma kurtardı |
| Kurtarma Hedefleri | veri kaybı ve kurtarma süresi eşiklerinin aşılması | veri kaybını sıfırlamak günde 2.800.000 onay turu, ayda 1555,52 reddedilen yazma | ayda 194,44 kalıcı kayıp kalkıyor (oran 8,00); 8 saniyelik pencere payına 211,50 arıza sığdırıyor |
| Yedeklilik Bölgeleri | makine, alan ve bölge kaybı | boşta kapasite $1/(n-1)$: iki alanda %100, altı alanda %20; iki bölgeli düzen makine kaybında 1 yazma kaybediyor | alan kaybında düşen yazma 126 → 0, kayıp 114 → 2 |
| Dağıtım Damgaları ve Coğrafi Kopyalar | damga içi bileşen arızası | bileşen 9 → 33 (coğrafi kopyayla 65); gün sonu işi damga sayısı kadar yere gidiyor | durum deposunun bulaşma kapsamı %100 → %25; damgayı geçen bağ 6 → 2 |
| Felaket Kurtarma Tatbikatı | denetimli arıza denemesi | ayda bir tatbikat 0,63 dakika (planlı payın %4,22'si), tepe yükte 19.527,82 uç isteği | planda 6 turluk kurtarma 19 tur ölçüldü (3,17 kat); 30 s hedef 38 saniyede kırılıyor |
| Etkisiz İşlemler | devralma ve yeniden denemede yinelenen istek | defter 3.200.000 kayıt / 230,40 MB (günlük artışın %23,61'i); yazma satırı ×2,00, okuma ×3,33 | ayda 8002 önlenen yan etki: 902 yinelenen ücret kalemi, 902 bildirim |
| Telafi Edici İşlemler | iş akışının yarıda kesilmesi | 8000 yazılmış telafi yolu, günde 60 koşan çağrı; sona taşınamayan geri alınamaz adım | telafisiz adım 80 → 60/gün; ikinci deneme askıda işi 2,979 → 0,171/gün |
| Talep Fişi Kalıbı | üretici ve tüketici çökmesi; kuyruk birikmesi | depoda 112,00 GB (saklamanın %15,72'si); günde 1968 yetim yük, 3948 sarkan fiş | kuyruk 4,4689 → 0,0316 Mbit/s; birikmede 3016,5 → 21,3 MB (141,6 kat) |
| Vale Anahtarı Kalıbı | kanıt deposunun yavaşlaması | günde 400.000 imzalama (tepede K01 ucunun %2,703'ü); 4166,7 anahtarlık açık pencere | düşen aktarım 28 → 0, tutulan yuva 64 → 0; kapsam daraltması 730 kat |
| Dış Yapılandırma Deposu | deponun düşmesi; yanlış değerin yazılması | depo okuma 0,1000/s; yayılma 25 s, karışık pencere 40 s | düşen istek 20.556 → 0 (arıza payının %2,36'sı); kademeli yaymada hatalı yanıt 61.668 → 20.556 |
| Boğucu İncir Geçişi | geçişin ortasında yeni sistemin durması | çift yazma yazma yolunu 37,04 → 74,08 yazma/s'ye çıkarıyor; cephe bütçeden 20 ms alıyor (180 → 160 ms) | düşen istek 25.305 → 422; geri alma çift yazmayla 1 tur, kesildikten bir gün sonra 3360,01 s |

Tablonun kuralı adıyla anılmalı: **bir kalıp iki sayı olmadan savunulamaz.** "Dayanıklılık sağlar"
cümlesi bu kursta karar taşımadı. İki sütun birbirinin yerine de geçmez — arızasız günün bedeli
her gün ödenir, arızalı günün kazancı yılda birkaç kez tahsil edilir; bir kalıbı seçmek bu iki
sıklığın çarpımını karşılaştırmaktır. Kursun kendi varsayımları (AY, KU, DD dizileri) K01'in
tablosuna karışmadı; her biri kendi adı ve duyarlılığıyla yazıldı.

Kursun bıraktığı soru bütün tablonun altındadır. Devre kesici bir eşiğin aşıldığını, devralma bir
kopyanın düştüğünü, geri basınç bir kuyruğun dolduğunu, dış yapılandırma deposu bir değerin yanlış
olduğunu **fark edildiğinde** çalışır. Farkın nasıl edileceği hiç tasarlanmadı: hangi ölçütün
toplanacağı, hangi eşiğin uyarı doğuracağı, yavaşlamanın hangi ölçümle görüneceği ve bir tasarımın
taşıyabileceği yükün nasıl sınanacağı hep varsayıldı. Sonraki kurs **Başarım Karşıt Kalıpları ve
İzleme** o katmanı ele alır.

