---
title: 'Ortam Terfisi'
source: 'https://academia.sh/tr/kurslar/ci-cd/ortam-terfisi'
course: 'Sürekli Tümleştirme ve Teslimat'
language: tr
updated: '2026-08-17T18:09:03+00:00'
license: 'CC BY-SA 4.0'
---

# Ortam Terfisi

Aynı yapı çıktısının ortamlar arasında terfi ettiği düzen ile her ortamda yeniden derleyen düzen aynı kırk adaylık dizide koşturulur: ortama özgü kusur, terfi kapısının tuttuğu, çıktı kimliğinin korunması ve terfi kapısında bekleyen çıktının süresi sayılır.

Değişiklik ortak gövdeye girdi ve tümleştirme kapısını geçti. Bu, değişikliğin üretimde olduğu
anlamına gelmiyor. Arada en az bir yapı çıktısı ve birkaç ortam var: geliştirme, hazırlık,
üretim. Bu dersin sorusu, o çıktının ortamlar arasında **nasıl** ilerlediğidir. İki düzen var.
Birincisinde çıktı bir kez üretilir ve her ortama aynı nesne terfi eder. İkincisinde her ortam
kendi derlemesini yapar; kaynak aynıdır, çıktı aynı olmak zorunda değildir.

Ortamların birbirine denk olup olmadığı ayrı bir ölçünün konusudur ve burada tekrarlanmıyor. Bu
ders denkliğin sağlandığı durumda bile kalan farkı ölçer: **çalışan nesnenin kendisinin farkını**.
Terfi kapısı bu derste bir onay kararıdır — bir çıktının bir sonraki ortama geçmesine izin verir
ya da vermez — ve kapının değeri, izin verdiği nesne ile sınadığı nesnenin aynı olmasına bağlıdır.

- **YS7.** Kurgusal bölgesel ölçüm ağının doğrulayıcı servisi için kırk yayın adayı üretilir; üç
  ortam vardır ve adaylar kırk günlük bir ufka yayılır. Ağ da rakamlar da kurgudur.
- **YS8.** Ortamlar yapılandırma ve veri açısından denk kabul edilir. Ortam denkliği ölçümü
  tekrarlanmıyor; buradaki tek fark kaynağı çıktının kendisidir.
- **YS9.** Bağımlılık çözümlemesi, çözüm anındaki en yeni sürümü seçer. Sekiz bağımlılığın sürüm
  çizelgesi kurgudur; sürüm sabitleme dosyası, aynalama ve elle sürüm seçimi modelin dışındadır.
- **YS10.** Kusur sınıfları üçtür: **kaynak kusuru** (her çıktıda vardır), **bağımlılık sürümü
  kusuru** (yalnız o sürümü içeren çıktıda vardır), **üretim ölçeğine bağlı kusur** (hiçbir
  terfi kapısında görünmez).
- **YS11.** Terfi kapısı dört saatte bir açılan pencerede koşar; üretim terfisi ayrıca sıfır ile
  sekiz saat arası onay bekler. Kapı koşumu on sekiz, derleme yirmi iki dakikadır.
- **YS12.** Çıktı kimliği, girdi kaydının özetinin ilk on iki onaltılık basamağıdır. Özet
  çakışması modelin dışındadır.

## Ölçüm Düzeneği

Ölçülen şey gerçek bir hat değil, `node` ile kurulan bir modeldir. Model bir bağımlılık sürüm
çizelgesi üretir, adayları bu çizelge üzerinde çözümler ve çıktı kimliğini `node:crypto` ile
gerçekten hesaplar. Rastgelelik üreteci kendi yazılmıştır, tohumu görünürdür.

```js
// terfi.mjs — ayni ciktinin terfi ettigi duzen ile her ortamda yeniden derleyen duzenin modeli
import { createHash } from 'node:crypto';
export const TOHUM = 20260902;
export const ADAY = 40, BAGIMLILIK = 8, UFUK_SA = 960, ARALIK_SA = 24;
export const DERLEME_DK = 22, KAPI_DK = 18, PENCERE_SA = 4;
export const KAYNAK = 0.25, OLCEK = 0.10, SURUM_KUSUR = 0.12, KARARSIZ = 0.05;
export const GELISTIRME_YAKALA = 0.45, HAZIRLIK_YAKALA = 0.75;

export function uretec(tohum) {                    // dogrusal eslesik uretec, tohum gorunur
  let x = tohum >>> 0;
  return () => { x = (Math.imul(x, 1664525) + 1013904223) >>> 0; return x / 4294967296; };
}
export const ozet = (aday, coz) =>                 // yapi ciktisinin kimligi: girdilerin ozeti
  createHash('sha256').update(JSON.stringify({ aday, coz: coz.map((v) => v.ad) })).digest('hex').slice(0, 12);

// Her bagimliligin bir surum cizelgesi vardir; cozumleme o andaki en yeni surumu secer.
export function cizelge(rnd) {
  return Array.from({ length: BAGIMLILIK }, (_, i) => {
    const s = [{ sa: 0, ad: `b${i}s1`, kusur: false }];
    for (let sa = 0; ;) {
      sa += 40 + Math.floor(rnd() * 200);
      if (sa >= UFUK_SA) break;
      s.push({ sa, ad: `b${i}s${s.length + 1}`, kusur: rnd() < SURUM_KUSUR });
    }
    return s;
  });
}
export const coz = (c, sa) => c.map((s) => s.filter((v) => v.sa <= sa).pop());

export function adaylar(rnd) {
  return Array.from({ length: ADAY }, (_, i) => ({
    no: i + 1, sa: Math.floor((i + 0.5) * (UFUK_SA / ADAY) + rnd() * 8),
    kaynak: rnd() < KAYNAK, olcek: rnd() < OLCEK,
    gd: rnd(), hd: rnd(), kd: rnd(), onay: Math.floor(rnd() * 9),
  }));
}
export const bekle = (sa) => (PENCERE_SA - (sa % PENCERE_SA)) % PENCERE_SA;

// yeniden=false: tek derleme, ayni cikti terfi eder. yeniden=true: her ortam kendi derlemesini yapar.
export function kostur(yeniden, aralik = ARALIK_SA) {
  const rnd = uretec(TOHUM), ciz = cizelge(rnd), ad = adaylar(rnd), kirmizi = uretec(TOHUM + 3);
  const s = { ozetAyni: 0, kaynakKacan: 0, olcekKacan: 0, gelMarj: 0, hazMarj: 0,
    ozguKacan: 0, sinananKacan: 0, tutulan: 0, yanlisTutulan: 0, farkliSurum: 0,
    dk: 0, bekleme: 0, bekleme1: 0, tepe: 0 };
  for (const a of ad) {
    const haz = yeniden ? coz(ciz, a.sa + 6) : coz(ciz, a.sa);
    const ur = yeniden ? coz(ciz, a.sa + 6 + aralik) : coz(ciz, a.sa);
    if (ozet(a.no, haz) === ozet(a.no, ur)) s.ozetAyni += 1;

    if (a.kaynak) {                                // kaynak kusuru her ciktida vardir
      const g = a.gd < GELISTIRME_YAKALA, h = a.hd < HAZIRLIK_YAKALA;
      if (g || h) s.tutulan += 1; else s.kaynakKacan += 1;
      if (g && !h) s.gelMarj += 1;                 // yalniz gelistirme kapisinda
      if (h && !g) s.hazMarj += 1;                 // yalniz hazirlik kapisinda
    }
    if (a.olcek) s.olcekKacan += 1;                // uretim olcegine bagli kusur: hicbir kapida gorunmez
    const sinanan = new Set(haz.map((v) => v.ad));
    s.farkliSurum += ur.filter((v) => !sinanan.has(v.ad)).length;
    for (const v of ur.filter((x) => x.kusur)) {
      if (!sinanan.has(v.ad)) s.ozguKacan += 1;    // uretimde var, sinanan ciktida yok
      else if (a.kd < HAZIRLIK_YAKALA) s.tutulan += 1;
      else s.sinananKacan += 1;
    }
    for (let k = 0; k < 2; k += 1) if (kirmizi() < KARARSIZ) s.yanlisTutulan += 1;

    s.dk += (yeniden ? 3 : 1) * DERLEME_DK + 2 * KAPI_DK;
    const gelis = a.sa + (yeniden ? DERLEME_DK / 60 : 0), b1 = bekle(gelis);
    const b2 = bekle(gelis + b1 + KAPI_DK / 60 + a.onay + (yeniden ? DERLEME_DK / 60 : 0));
    s.bekleme += b1 + b2; s.bekleme1 += b1; s.tepe = Math.max(s.tepe, b1 + b2);
  }
  return { ...s, ortBekleme: s.bekleme / ADAY };
}
```

Modelin tek anahtarı `yeniden`. Kapalıyken çıktı adayın hazır olduğu anda bir kez çözümlenir ve
üç ortamda da o çözümleme geçerlidir. Açıkken hazırlık kendi derlemesini altıncı saatte, üretim
yirmi dört saat sonra yapar. Kaynak her üç derlemede de aynıdır; değişen tek şey **ne zaman**
çözümlendiğidir.

## İki Düzen, Aynı Aday Dizisi

```js
// kosum1.mjs — ayni aday dizisi iki terfi duzeninde kosturulur
import { kostur, ozet, cizelge, adaylar, uretec, coz, TOHUM, ADAY, ARALIK_SA } from './terfi.mjs';

console.log(`tohum ${TOHUM} | ${ADAY} aday, 8 bagimlilik, uc ortam, uretim derlemesi hazirliktan ${ARALIK_SA} sa sonra`);
console.log('duzen           ozet   farkli  ortama  sinanip  kaynak  olcek   yanlis  hat    bekleme  tepe');
console.log('                ayni   surum   ozgu    kacan    kacan   kacan   tutulan dk     ort/sa   sa');
for (const [ad, y] of [['ayni cikti', false], ['yeniden derle', true]]) {
  const s = kostur(y);
  console.log(`${ad.padEnd(15)} ${`${s.ozetAyni}/${ADAY}`.padEnd(6)} ${String(s.farkliSurum).padEnd(7)} ` +
    `${String(s.ozguKacan).padEnd(7)} ${String(s.sinananKacan).padEnd(8)} ${String(s.kaynakKacan).padEnd(7)} ` +
    `${String(s.olcekKacan).padEnd(7)} ${String(s.yanlisTutulan).padEnd(7)} ${String(s.dk).padEnd(6)} ` +
    `${s.ortBekleme.toFixed(2).padEnd(8)} ${s.tepe.toFixed(2)}`);
}
const t = kostur(false);
console.log(`\nterfi kapilarinin marjinal degeri (iki duzende de ayni kaynak kusuru kumesi):`);
console.log(`  yalniz gelistirme kapisinda yakalanan: ${t.gelMarj}`);
console.log(`  yalniz hazirlik kapisinda yakalanan:   ${t.hazMarj}`);
console.log(`  gelistirme kapisinin faturasi: ${ADAY * 18} dk kapi suresi + ${t.bekleme1.toFixed(1)} sa pencere beklemesi`);

const rnd = uretec(TOHUM), ciz = cizelge(rnd), ad = adaylar(rnd);
const a = ad.find((x) => ozet(x.no, coz(ciz, x.sa + 6)) !== ozet(x.no, coz(ciz, x.sa + 6 + ARALIK_SA)));
const h = coz(ciz, a.sa + 6), u = coz(ciz, a.sa + 6 + ARALIK_SA);
console.log(`\naday ${a.no} (yeniden derleyen duzen):`);
console.log(`  hazirlikta sinanan cikti: ${ozet(a.no, h)}`);
console.log(`  uretime giden cikti:      ${ozet(a.no, u)}`);
console.log(`  ayrisan bagimlilik: ${h.map((v, i) => v.ad === u[i].ad ? null : `${v.ad} -> ${u[i].ad}`).filter(Boolean).join(', ')}`);
```

```
tohum 20260902 | 40 aday, 8 bagimlilik, uc ortam, uretim derlemesi hazirliktan 24 sa sonra
duzen           ozet   farkli  ortama  sinanip  kaynak  olcek   yanlis  hat    bekleme  tepe
                ayni   surum   ozgu    kacan    kacan   kacan   tutulan dk     ort/sa   sa
ayni cikti      40/40  0       0       5        3       4       5       2320   3.93     6.70
yeniden derle   9/40   56      2       4        3       4       5       4080   4.19     6.97

terfi kapilarinin marjinal degeri (iki duzende de ayni kaynak kusuru kumesi):
  yalniz gelistirme kapisinda yakalanan: 1
  yalniz hazirlik kapisinda yakalanan:   7
  gelistirme kapisinin faturasi: 720 dk kapi suresi + 59.0 sa pencere beklemesi

aday 2 (yeniden derleyen duzen):
  hazirlikta sinanan cikti: 52d6a529d9a3
  uretime giden cikti:      1f9f016e7cfb
  ayrisan bagimlilik: b6s1 -> b6s2
```

İlk sütun dersin çekirdeğidir. Aynı çıktının terfi ettiği düzende kırk adayın kırkında üretimdeki
nesne hazırlıkta sınanan nesnedir. Yeniden derleyen düzende bu sayı dokuza iner: **otuz bir
adayda üretim, hiçbir kapının görmediği bir çıktıyı çalıştırdı**. Ayrışan bağımlılık sürümü sayısı
elli altı — kırk aday boyunca elli altı kez, üretime giden çıktıdaki bir bağımlılık hazırlıkta
sınanan çıktıdakinden başkaydı.

Bu ayrışmanın zararı ikinci sütunda: iki ortama özgü kusur. Sayı küçük görünüyor, ama niteliği
başka. Sınanıp kaçan dört kusur, kapının **baktığı ve göremediği** kusurdur; kapının yakalama
oranı yükselirse azalır. İki ortama özgü kusur ise kapının **bakmadığı** kusurdur — o sürüm hiçbir
ortamda çalıştırılmadı. Kapının yakalama oranını yüzde yüze çıkarmak bu ikisini sıfırlamaz.

Kaynak kusuru ve ölçek kusuru sütunları iki düzende de aynı: üç ve dört. Bu beklenen sonuçtur ve
ölçümün tutarlılık kontrolüdür. Terfi düzeni, kaynağın kendi kusurunu ne azaltır ne çoğaltır;
yalnız sınanan nesne ile çalışan nesne arasındaki bağı kurar ya da koparır.

Alttaki blok tek bir adayı gösteriyor. İkinci adayın hazırlıkta sınanan çıktısının özeti
`52d6a529d9a3`, üretime gidenin `1f9f016e7cfb`. Kaynak aynı, aday aynı, tek fark altıncı
bağımlılığın `b6s1` yerine `b6s2` sürümüne çözülmesi. Hiç kimse bir karar vermedi; yalnız yirmi
dört saat geçti.

## Ayrışma Neyin İşlevi

```js
// kosum2.mjs — hazirlik derlemesi ile uretim derlemesi arasindaki aralik taranir
import { kostur, ADAY } from './terfi.mjs';

console.log('aralik  ozet    ayrisan  ortama  sinanip  hat    bekleme');
console.log('(sa)    ayni    surum    ozgu    kacan    dk     ort/sa');
for (const a of [2, 6, 12, 24, 48, 96]) {
  const s = kostur(true, a);
  console.log(`${String(a).padEnd(7)} ${`${s.ozetAyni}/${ADAY}`.padEnd(7)} ${String(s.farkliSurum).padEnd(8)} ` +
    `${String(s.ozguKacan).padEnd(7)} ${String(s.sinananKacan).padEnd(8)} ${String(s.dk).padEnd(6)} ${s.ortBekleme.toFixed(2)}`);
}
console.log('\nayni ciktinin terfi ettigi duzende bu satirlarin hepsi: 40/40 ozet ayni, 0 ayrisan surum, 0 ortama ozgu');
```

```
aralik  ozet    ayrisan  ortama  sinanip  hat    bekleme
(sa)    ayni    surum    ozgu    kacan    dk     ort/sa
2       36/40   4        0       5        4080   4.19
6       24/40   18       0       4        4080   4.19
12      17/40   31       1       4        4080   4.19
24      9/40    56       2       4        4080   4.19
48      0/40    104      4       4        4080   4.19
96      0/40    192      8       1        4080   4.19

ayni ciktinin terfi ettigi duzende bu satirlarin hepsi: 40/40 ozet ayni, 0 ayrisan surum, 0 ortama ozgu
```

Tarama ayrışmanın neyin işlevi olduğunu söylüyor: **geçen zamanın**. İki saatlik aralıkta bile
kırk adayın dördü kimliğini kaybediyor. Kırk sekiz saatte hiçbir aday kimliğini korumuyor. Kimse
sürüm değiştirmiyor, kimse yapılandırmaya dokunmuyor; yalnız çözümleme iki kez yapılıyor ve
arasında dünya ilerliyor.

Son satır sessiz bir yer değiştirmeyi gösteriyor. Doksan altı saatlik aralıkta sınanıp kaçan
kusur beşten bire düşüyor — kapı daha iyi çalıştığı için değil, o kusurların artık **sınanmayan**
sütununa geçtiği için. Bir kapının kaçırdığı sayının düşmesi tek başına iyi haber değildir;
kapının baktığı küme küçülmüş de olabilir.

Hat dakikası ile bekleme sütunları tarama boyunca sabit kalıyor: dört bin seksen dakika ve aday
başına dört saat on bir dakika. Aralığı kısaltmak ne makine süresi kazandırıyor ne bekleme.
Yeniden derleyen düzende ayrışmayı azaltmanın tek yolu iki derlemeyi birbirine yaklaştırmaktır,
ve o yaklaştırma sıfıra ulaştığında elde kalan şey zaten tek derlemedir. Yani tarama, iki düzenin
arasında bir orta yol olmadığını gösteriyor: aralık ne kadar küçülürse küçülsün ayrışma olasılığı
sıfırlanmıyor, sıfırlanan tek nokta ikinci derlemenin hiç yapılmadığı noktadır.

## Kapının Üç Sayısı ve Kaldırılabilir Kapı

**Tuttuğu:** kırk adaylık dizide iki terfi kapısı birlikte on kaynak kusurundan yedisini ve
sınanan çıktıdaki bağımlılık kusurlarının çoğunu tuttu. **Yalnız kendisinin tuttuğu:** hazırlık
kapısı yedi, geliştirme kapısı bir. **Kaçırdığı:** üç kaynak kusuru, dört ölçek kusuru, artı
yeniden derleyen düzende iki ortama özgü kusur. **Yanlış tuttuğu:** beş temiz aday. **Eklediği
süre:** aday başına ortalama üç saat elli altı dakika bekleme, tepe altı saat kırk iki dakika;
hat süresi iki bin üç yüz yirmi dakika, yeniden derleyen düzende dört bin seksen.

Geliştirme kapısının hesabı kendi kendini yazıyor: kırk adayda yalnız bir kusuru tek başına
yakaladı, karşılığında yedi yüz yirmi dakika kapı süresi ve elli dokuz saat pencere beklemesi
istedi. Hazırlık kapısı aynı süreye yedi kusur veriyor. Bu sayılarla geliştirme kapısını
kaldırmak savunulabilir bir karardır: kırk adayda bir kusurun daha geç yakalanması karşılığında
her aday bir pencere erken ilerler. Kararı veren şey kapının fikri değil, marjinali.

Aynı hesap yeniden derleyen düzen için başka bir sonuç veriyor. O düzende hazırlık kapısının
yedi kusurluk marjinali **sınadığı nesne için** geçerli; üretime giden nesne otuz bir adayda
başkası. Kapı çalışıyor, sayıları da iyi — ama kanıtı taşıdığı nesneyle birlikte gitmiyor.
Kaldırılması gereken şey kapı değil, kapının kanıtını geçersiz kılan ikinci derlemedir.

## Özet

- Aynı çıktının terfi ettiği düzende kırk adayın kırkında üretim, hazırlıkta sınanan nesneyi
  çalıştırdı; yeniden derleyen düzende bu sayı dokuz, ayrışan bağımlılık sürümü elli altı oldu.
- Ayrışma iki ortama özgü kusur üretti: kapının bakmadığı, dolayısıyla yakalama oranı yükselerek
  azalmayacak bir kusur sınıfı.
- Kaynak kusuru üç, ölçek kusuru dört: iki düzende de aynı. Terfi düzeni kaynağın kusurunu
  değiştirmez, yalnız sınanan nesne ile çalışan nesne arasındaki bağı kurar ya da koparır.
- Ayrışma zamanın işlevidir: iki saatlik aralıkta kırk adayın dördü, kırk sekiz saatlik aralıkta
  hepsi kimliğini kaybetti. Doksan altı saatte kaçan kusur sayısının düşmesi kapının iyileşmesi
  değil, baktığı kümenin küçülmesidir.
- Geliştirme terfi kapısı kırk adayda yalnız bir kusuru tek başına yakaladı ve yedi yüz yirmi
  dakika ile elli dokuz saat pencere beklemesi istedi; bu sayılarla kaldırılması savunulabilir.
- Terfi kapısının bekletme faturası aday başına ortalama üç saat elli altı dakika, tepe altı saat
  kırk iki dakikadır; yeniden derleyen düzen buna aday başına iki fazladan derleme ekler.

## Sonraki Adım

Bu ölçümde üretime terfi tek bir karardı: çıktı ya geçti ya geçmedi, geçtiğinde de tamamına açıldı.
Oysa terfi tek adımda olmak zorunda değil. Yeni sürüm önce isteklerin küçük bir yüzdesine
açılabilir, bir süre izlenebilir, sonra yüzde artırılabilir. Bu, kapıyı tek karardan bir karar
dizisine dönüştürür ve yeni bir soru açar: yüzdeyi artırma kararını hangi ölçüt veriyor, o ölçüt
ne kadarlık bir pencerede toplanıyor ve eşiği nedir. Sonraki ders bu üç ayarı tarar; ölçüt
gürültülüyken temiz bir sürümün durdurulmasını da sayar.
