Ders 10 / 12
Derleme Ortamı Yalıtımı
Derleme ortamının yetkisi kalem kalem sayılır: hat kaç kaleme erişiyor, kaçını gerçekten gereksiniyor, yalıtımdan sonra kaç erişim çifti kalıyor ve neden kalıyor, ağ tümden kapatıldığında kaç adım kırılıyor, depo dışından gelen bir değişiklik koştuğunda kaç sır erişilebilir durumda oluyor.
İçindekiler
Önceki ders köken belgesinin on dört alanından yedisinin hiçbir koşulda sınanamadığını saydı. O yedinin dördü tek bir konuyu anlatıyordu: çalıştırıcı türü, yalıtım düzeyi, ağ erişimi ve ortam değişkeni adları. Dördü de belgede yazıyordu, dördü de beyandı ve değerleri yalnız o ortamın gerçekten öyle kurulmuş olmasına bağlıydı.
Bu ders o ortamı kalem kalem sayar. Ölçü, derleme ortamının eriştiği kalem sayısı ile gerçekten gereksindiği kalem sayısı arasındaki farktır. Sürekli Tümleştirme ve Teslimat kursunda hat güvenliği ve sır yönetimi dağıtım ekseninde ölçülmüştü; o ölçüm tekrarlanmaz. Buradaki nesne hattın kendi yetkisidir. Sayım savunma tarafındadır: hangi kalemin hangi adımdan erişilebilir durumda olduğu envanterden hesaplanır, erişimin nasıl kullanılacağı yazılmaz.
TZ15. Kurgu hat beş adımdır ve erişim kalemleri dört türde on sekiz kalemdir; küme node
ile modellenir. Her kalemin hangi adım tarafından gerçekten gereksinildiği de kurgudur.
TZ16. Paylaşılan çalıştırıcıda her adım her kaleme erişir; ölçü birimi erişim çiftidir
— bir adımın bir kaleme erişebilir olması bir çifttir.
Derleme Ortamı Neye Erişiyor
// olcum-agi/erisim-envanteri.mjs — derleme ortami hangi kaleme erisiyor, kaci gerekiyor import { mkdirSync, writeFileSync } from "node:fs"; import { join } from "node:path"; const KOK = join(process.env.TMPDIR ?? "/tmp", "olcum-agi-tz"); mkdirSync(KOK, { recursive: true }); // Kurgu bolgesel olcum agi: abone portalinin hatti bes adimdan olusur. const ADIM = ["bagimlilik-cek", "derle", "sina", "paketle", "yayimla"]; // Kalem envanteri modeldir: tur, ad ve kalemi GERCEKTEN gereksinen adimlar. const KALEM = [ ["sir", "yapi-ciktisi-deposu-jetonu", ["yayimla"]], ["sir", "kaynak-deposu-anahtari", []], ["sir", "imza-gizli-anahtari", ["yayimla"]], ["sir", "bulut-kimligi", []], ["sir", "veritabani-parolasi", ["sina"]], ["sir", "bildirim-jetonu", ["yayimla"]], ["ag", "paket-aynasi", ["bagimlilik-cek"]], ["ag", "yapi-ciktisi-deposu", ["yayimla"]], ["ag", "imza-hizmeti", ["yayimla"]], ["ag", "genel-internet", []], ["ag", "ic-servis-agi", ["sina"]], ["yol", "kaynak-agaci", ["derle", "sina", "paketle"]], ["yol", "onbellek", ["bagimlilik-cek", "derle"]], ["yol", "onceki-is-artiklari", []], ["yol", "calistirici-kok", []], ["kimlik", "hat-hesabi", ["yayimla"]], ["kimlik", "kap-kayit-defteri", ["paketle"]], ["kimlik", "yonetim-duzlemi", []], ]; writeFileSync(join(KOK, "kalemler.json"), JSON.stringify({ ADIM, KALEM })); // Paylasilan calistiricida her adim her kaleme erisir: erisim cifti = adim x kalem. const TUR = ["sir", "ag", "yol", "kimlik"]; const S = [10, 8, 16, 15, 0]; const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(S[i])).join("")); satir(["tur", "kalem", "hic gerekmeyen", "erisim cifti", "gerekli cift"]); let toplamCift = 0, toplamGerekli = 0, hicGereken = 0; for (const t of TUR) { const kume = KALEM.filter(([tur]) => tur === t); const cift = kume.length * ADIM.length; const gerekli = kume.reduce((n, [, , g]) => n + g.length, 0); const bos = kume.filter(([, , g]) => g.length === 0).length; toplamCift += cift; toplamGerekli += gerekli; hicGereken += bos; satir([t, kume.length, bos, cift, gerekli]); } console.log(""); console.log(`adim ${ADIM.length}, kalem ${KALEM.length}; erisim cifti ${toplamCift}, ` + `gerekli ${toplamGerekli}, gereksiz ${toplamCift - toplamGerekli}`); console.log(`hicbir adimin gereksinmedigi kalem ${hicGereken}: ` + KALEM.filter(([, , g]) => g.length === 0).map(([, a]) => a).join(", "));
tur kalem hic gerekmeyen erisim cifti gerekli cift sir 6 2 30 4 ag 5 1 25 4 yol 4 2 20 5 kimlik 3 1 15 2 adim 5, kalem 18; erisim cifti 90, gerekli 15, gereksiz 75 hicbir adimin gereksinmedigi kalem 6: kaynak-deposu-anahtari, bulut-kimligi, genel-internet, onceki-is-artiklari, calistirici-kok, yonetim-duzlemi
Paylaşılan bir çalıştırıcıda beş adım on sekiz kaleme erişir ve bu 90 erişim çifti eder. Bu çiftlerin 15’i gereklidir; kalan 75’i hiçbir adımın işine yaramaz ve hiçbiri bir karar sonucu değildir. Kimse “derleme adımı imza gizli anahtarını görsün” demedi; adımlar aynı çalıştırıcıda koştuğu için gördü.
En keskin sayı üçüncü sütundadır: on sekiz kalemin altısı hiçbir adım tarafından gereksinilmiyor. Kaynak deposu anahtarı ile bulut kimliği hattın önceki bir sürümünden kalmıştır, genel internet erişimi hiçbir adımın hedef listesinde yoktur, önceki iş artıkları ile çalıştırıcı kökü paylaşılan makinenin kendi içeriğidir, yönetim düzlemi kimliği ise hiç kullanılmamış geniş kapsamlı bir jetondur. Altı kalem hattın hiçbir işine yaramadan hattın tamamında duruyor.
Bu altı kalem envanteri tutulduğu anda görülür. Ölçünün asıl işi de budur: yetki daraltma bir ilke olarak söylendiğinde karar taşımaz, çift olarak sayıldığında hangi kalemin hangi adımda ne işe yaradığı yazılabilir hale gelir. Bir kalemin gereksinen adım listesi boşsa o kalem düşürülür; boş değilse liste zaten daraltmanın hedefidir.
Yalıtımdan Sonra Kalanlar
Yalıtım iki ayrı iş yapar: gereksinilmeyen kalemi tümden düşürmek ve kalan kalemin erişimini gereksinen adıma daraltmak. İkincisi her kalemde aynı ölçüde mümkün değildir.
TZ17. Daraltmanın bağlandığı düzey kalemin veriliş biçimine göre değişir ve iki değer alır: adım düzeyi ya da iş düzeyi. Bu bir modeldir. TZ18. Süreler veri olarak verilmiştir, ölçülmüş değildir: iş başına yeni çalıştırıcı 38 saniye, sır kapsamı daraltma 6 saniye, ağ izin listesi 2 saniye.
// olcum-agi/yalitim.mjs — yalitimdan sonra kac kalem kaliyor ve neden kaliyor import { readFileSync } from "node:fs"; import { join } from "node:path"; const KOK = join(process.env.TMPDIR ?? "/tmp", "olcum-agi-tz"); const { ADIM, KALEM } = JSON.parse(readFileSync(join(KOK, "kalemler.json"))); // Daraltmanin BAGLANDIGI duzey kalemin verilis bicimine gore degisir; bu bir modeldir. // "adim": kalem yalniz gereksinen adima verilebilir. "is": duzenek is duzeyinde baglanir. const DUZEY = { "yapi-ciktisi-deposu-jetonu": "adim", "imza-gizli-anahtari": "adim", "bildirim-jetonu": "adim", "kap-kayit-defteri": "adim", "hat-hesabi": "adim", "veritabani-parolasi": "is", // ortam degiskeni olarak isin tamamina konuyor "paket-aynasi": "is", "yapi-ciktisi-deposu": "is", // izin listesi calistirici duzeyinde "imza-hizmeti": "is", "ic-servis-agi": "is", "kaynak-agaci": "is", "onbellek": "is", // calisma alani baglamasi is duzeyinde }; // Yalitim iki is yapar: gereksinilmeyen kalem tumden dusurulur, kalan kalem daraltilir. const kalan = KALEM.filter(([, , g]) => g.length > 0); const erisen = ([, ad, g]) => (DUZEY[ad] === "adim" ? g.length : ADIM.length); const TUR = ["sir", "ag", "yol", "kimlik"]; const S = [10, 18, 12, 14, 0]; const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(S[i])).join("")); satir(["tur", "kalem once/sonra", "cift once", "cift sonra", "kalan gereksiz"]); let once = 0, sonra = 0, gerekli = 0; for (const t of TUR) { const hepsi = KALEM.filter(([tur]) => tur === t); const k = kalan.filter(([tur]) => tur === t); const c1 = hepsi.length * ADIM.length; const c2 = k.reduce((n, e) => n + erisen(e), 0); const g = k.reduce((n, [, , gg]) => n + gg.length, 0); once += c1; sonra += c2; gerekli += g; satir([t, `${hepsi.length}/${k.length}`, c1, c2, c2 - g]); } console.log(""); console.log(`erisim cifti ${once} -> ${sonra}; gerekli ${gerekli}, ` + `kalan gereksiz ${sonra - gerekli}`); console.log("is duzeyinde bagli kalan: " + kalan.filter(([, ad]) => DUZEY[ad] === "is").map(([, ad]) => ad).join(", ")); // Ag tumden kapatilsaydi: bir ag kalemi gereksinen her adim kirilir. const agliAdim = [...new Set(kalan.filter(([t]) => t === "ag").flatMap(([, , g]) => g))]; console.log(`ag tumden kapatilirsa kirilan adim ${agliAdim.length}/${ADIM.length}: ` + agliAdim.join(", ")); // Sureler VERI olarak verilmistir, olculmus degil. const [YENI_CALISTIRICI, SIR_DARALTMA, IZIN_LISTESI, KOSUM] = [38, 6, 2, 30]; const ek = YENI_CALISTIRICI + SIR_DARALTMA + IZIN_LISTESI; console.log(`yalitimin kosum basina ek suresi ${ek} s (${YENI_CALISTIRICI}+${SIR_DARALTMA}+` + `${IZIN_LISTESI}), ${KOSUM} kosumda ${ek * KOSUM} s; sureler veri olarak verildi`);
tur kalem once/sonra cift once cift sonra kalan gereksiz sir 6/4 30 8 4 ag 5/4 25 20 16 yol 4/2 20 10 5 kimlik 3/2 15 2 0 erisim cifti 90 -> 40; gerekli 15, kalan gereksiz 25 is duzeyinde bagli kalan: veritabani-parolasi, paket-aynasi, yapi-ciktisi-deposu, imza-hizmeti, ic-servis-agi, kaynak-agaci, onbellek ag tumden kapatilirsa kirilan adim 3/5: bagimlilik-cek, yayimla, sina yalitimin kosum basina ek suresi 46 s (38+6+2), 30 kosumda 1380 s; sureler veri olarak verildi
Erişim çifti 90’dan 40’a iner ve gerekli olan 15’tir. Kazanç gerçektir: on sekiz kalemin altısı düşürülür, kalan on ikisinin erişimi daraltılır. Ama kalan gereksiz çift sayısı sıfır değil 25’tir ve bu satır dersin asıl sorusudur: kalanlar neden kaldı?
Cevap türlere göre değişir. Kimlik satırında kalan gereksiz sıfırdır, çünkü jeton adıma özgü verilebilir: yapı hesabı yalnız yayımlama adımında, kayıt defteri kimliği yalnız paketleme adımında durur. Sır satırında kalan gereksiz dörttür ve dördü tek bir kalemden gelir — veritabanı parolası sınama adımına ortam değişkeni olarak veriliyor, ortam değişkeni ise işin tamamına konuyor. Bir tek kalemin veriliş biçimi, o kalemi beş adımın hepsine açıyor.
Ağ satırı en kötüsüdür: dört hedef kalır, hepsi iş düzeyinde bağlıdır ve 16 gereksiz çift üretir. Nedeni ağ izin listesinin çalıştırıcı düzeyinde uygulanmasıdır; liste “bu iş şu dört hedefe çıkabilir” der, “derleme adımı yalnız paket aynasına çıkabilir” diyemez. Aynı biçimde çalışma alanı bağlaması iş düzeyindedir: kaynak ağacı ile önbellek, gereksinmeyen adımlara da açık kalır. Daraltmanın sınırı ilkede değil, kalemin veriliş düzeneğindedir.
Üçüncü çıktı satırı bir öncekiyle bağ kurar. Köken belgesinde ağ erişimi alanı “kapalı” yazıyordu ve sınanamıyordu. Burada sayı şunu söylüyor: ağ tümden kapatılırsa beş adımın üçü kırılır — bağımlılık çekme, sınama ve yayımlama. O alan yalnız doğrulanamaz değil, yazıldığı biçimde doğru da olamaz. Doğru olabilecek tek biçim “dört hedefe izinli” gibi bir listedir ve o liste bir kanıt değil, yine bir beyandır.
Son satır bedeli yazar. Yalıtım koşum başına 46 saniye ekler, otuz koşumda 1.380 saniye. Bu sürenin karşılığı 50 erişim çiftinin kapanmasıdır; kalan 25 çift için ödenen bir şey yoktur, çünkü onlar süreyle değil düzenekle kapanır.
Depo Dışından Gelen Değişiklik
Erişim çifti kimin değişikliğinin koştuğuna bakmaz. Aynı kalemler, deponun içinden gelen bir değişiklik için de dışından gelen bir katkı için de aynı adımlara açıktır.
TZ19. Otuz koşumun sekizi depo dışından gelen bir değişiklikle tetiklenir; yalıtılmış yapılandırmalarda dış katkıda yayımlama adımı atlanır. Bir adım, gereksindiği kalemlerden biri o hatta hiç yoksa koşamaz.
// olcum-agi/dis-katki.mjs — depo disindan gelen bir degisiklik kostugunda kac sir erisilebilir import { readFileSync } from "node:fs"; import { join } from "node:path"; const KOK = join(process.env.TMPDIR ?? "/tmp", "olcum-agi-tz"); const { ADIM, KALEM } = JSON.parse(readFileSync(join(KOK, "kalemler.json"))); const DUZEY = { "yapi-ciktisi-deposu-jetonu": "adim", "imza-gizli-anahtari": "adim", "bildirim-jetonu": "adim", "kap-kayit-defteri": "adim", "hat-hesabi": "adim", "veritabani-parolasi": "is", "paket-aynasi": "is", "yapi-ciktisi-deposu": "is", "imza-hizmeti": "is", "ic-servis-agi": "is", "kaynak-agaci": "is", "onbellek": "is", }; // Kurgu: otuz kosumun sekizi depo disindan gelen bir degisiklikle tetikleniyor. const KOSUM = 30, DIS = 8; const kalan = KALEM.filter(([, , g]) => g.length > 0); const SIR = KALEM.filter(([t]) => t === "sir").map(([, ad]) => ad); // Uc yapilandirma: ic degisiklik kumesi, dis katki kumesi, daraltma, atlanan adim. const YAPI = [ ["paylasilan calistirici", KALEM, KALEM, false, []], ["yalitilmis hat", kalan, kalan, true, ["yayimla"]], ["dis katkiya sirsiz hat", kalan, kalan.filter(([t, ad]) => t !== "sir" && ad !== "ic-servis-agi"), true, ["yayimla"]], ]; // Bir kalem, erisim duzeyi ile kosan adimlarin kesisimi bos degilse erisilebilirdir. const erisilir = (kume, daralt, kosan, ad) => { const kalem = kume.find(([, a]) => a === ad); if (kalem === undefined) return false; return (daralt && DUZEY[ad] === "adim" ? kalem[2] : ADIM).some((a) => kosan.includes(a)); }; const S = [26, 10, 11, 17, 0]; const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(S[i])).join("")); satir(["yapilandirma", "ic: sir", "dis: sir", "dis: kosmayan", "sekiz katkida sir-kosum"]); const sonuc = []; for (const [ad, icKume, disKume, daralt, atlanan] of YAPI) { const disKosan = ADIM.filter((a) => !atlanan.includes(a)); const ic = SIR.filter((s) => erisilir(icKume, daralt, ADIM, s)).length; const dis = SIR.filter((s) => erisilir(disKume, daralt, disKosan, s)).length; // Bir adim, gereksindigi kalemlerden biri o hatta hic yoksa kosamaz. const kirik = disKosan.filter((a) => KALEM.some(([, kad, g]) => g.includes(a) && !disKume.some(([, b]) => b === kad))); sonuc.push([ad, kirik]); satir([ad, ic, dis, [...atlanan, ...kirik].join(", ") || "-", dis * DIS]); } console.log(""); console.log(`kosum ${KOSUM}, depo disindan gelen ${DIS}; hattaki sir ${SIR.length}, ` + `yalitimdan sonra kalan ${kalan.filter(([t]) => t === "sir").length}`); const [sonAd, sonKirik] = sonuc.at(-1); console.log(`${sonAd}: kosamayan adim ${sonKirik.join(", ")}; ${DIS} dis katki ` + `entegrasyon sinamasi gormeden inceleme kuyruguna giriyor`);
yapilandirma ic: sir dis: sir dis: kosmayan sekiz katkida sir-kosum paylasilan calistirici 6 6 - 48 yalitilmis hat 4 1 yayimla 8 dis katkiya sirsiz hat 4 0 yayimla, sina 0 kosum 30, depo disindan gelen 8; hattaki sir 6, yalitimdan sonra kalan 4 dis katkiya sirsiz hat: kosamayan adim sina; 8 dis katki entegrasyon sinamasi gormeden inceleme kuyruguna giriyor
İlk satır sayıyı en yalın biçimde verir: paylaşılan çalıştırıcıda depo dışından gelen bir değişiklik altı sırrın altısını erişilebilir bulur ve sekiz katkı boyunca bu 48 sır-koşum çifti eder. Değişikliğin ne yaptığı önemli değildir; ortam onu kendi değişikliğinden ayırmaz, çünkü ayırmasını sağlayacak bir kalem yoktur.
İkinci satırda erişilebilen sır 1‘e iner ve düşüşün kaynağı ikiye bölünür. İki sır zaten düşürülmüştür, üçü yayımlama adımına bağlıdır ve dış katkıda o adım koşmaz. Geriye kalan tek sır yine veritabanı parolasıdır: iş düzeyinde bağlı olduğu için sınama adımıyla birlikte gelir. Yalıtımın bu yapılandırmadaki kazancı 48 çiftten 8 çifte inmektir ve kalan 8’in tamamı tek bir kalemin veriliş biçiminden doğar.
Üçüncü satır o kalemi de kaldırır ve bedeli hemen görünür. Sırsız hatta erişilebilen sır sıfırdır, ama sınama adımı koşamaz — veritabanı parolası ve iç servis ağı orada yoktur. Sekiz dış katkı entegrasyon sınaması görmeden inceleme kuyruğuna girer. Bu, yalıtımın işe yaramadığı yer değildir; fiyatının başka bir kalemden ödendiği yerdir. Sıfır erişim ile sınanmış katkı aynı anda elde edilmiyor ve ikisi arasındaki seçim sekiz katkının ne kadar incelendiğine bağlı bir karardır, bir ilke sorusu değil.
Özet
- Beş adımlı hat on sekiz kaleme erişir: 90 erişim çiftinin yalnız 15’i gereklidir. On sekiz kalemin 6’sı hiçbir adım tarafından gereksinilmez ve hattın tamamında durur.
- Yalıtım erişim çiftini 90’dan 40’a indirir; 25 çift gereksiz kalır. Kimlik türünde kalan gereksiz 0, ağ türünde 16’dır.
- Kalanların nedeni ilkede değil düzenektedir: ağ izin listesi çalıştırıcı düzeyinde, çalışma alanı bağlaması iş düzeyinde uygulanır, bir sır ortam değişkeni olarak işin tamamına konur.
- Ağ tümden kapatılırsa beş adımın 3’ü kırılır; köken belgesindeki “ağ erişimi kapalı” beyanı yalnız doğrulanamaz değil, yazıldığı biçimde doğru da olamaz. Yalıtım koşum başına 46 saniye, otuz koşumda 1.380 saniye ekler.
- Depo dışından gelen değişiklik paylaşılan çalıştırıcıda 6 sırra erişir (sekiz katkıda 48 çift), yalıtılmış hatta 1 sırra (8 çift), sırsız hatta 0 sırra — ama sırsız hatta sınama adımı koşmaz ve sekiz katkı sınanmadan incelemeye girer.
Sonraki Adım
Derleme ortamının yetkisi sayıldı: kaç kaleme erişiliyor, kaçı gerekiyor, yalıtımdan sonra ne kalıyor ve neden kalıyor. Bütün bu ölçüm hattın kendi kalemleri üzerineydi. Oysa aynı hattın ilk adımı bağımlılık çekmedir ve o adım, envanterdeki yetmiş üç kaydı hatta getiren adımdır. Yetki daraltma o kayıtların hiçbirine dokunmaz: bir bileşen hatta girdiğinde ortamın ne kadar dar olduğu değil, o bileşenin ne olduğu belirleyicidir.
Sonraki ders bu soruyu bir kural kümesine çevirir. Envanterdeki kayıtlar bir politikadan geçirilir ve ölçü yine iki sayıdır: politika kaç bileşeni işaretliyor ve işaretlerin kaçı yanlış? Terkedilmiş paket kuralı en çok işaret üreten kuraldır; ürettiği işaretlerin kaçı gerçekten bir sorunu gösteriyor, kaçı yalnız bir tarih alanının eskimesini gösteriyor?
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.