Ders 14 / 21
Geri Alma Planı
Geri alma bir düğme olarak değil plan olarak modellenir: üç senaryo (yalnız kod, kod ve yapılandırma, kod ve veri) adım adım koşturulur, her adımın turu sayılır ve dönüşü olmayan noktanın kaçıncı adım olduğu bulunur. Provası yapılmamış planın ilk koşumda kaç adımda takıldığı ve ön koşul denetiminin kapı olarak değeri ölçülür.
İçindekiler
Bayrak kapatmak, geri alınacak şey bir davranışsa bir tur sürer. Kusur bayraklanmamış bir değişiklikteyse, yapılandırma da değişmişse ya da yayınla birlikte veri dönüştürülmüşse geri dönüş tek anahtar değildir. Sıralı adımlar vardır, adımların ön koşulları vardır ve bazı adımlardan sonra geri dönüş kapanır.
Bu dersin ölçtüğü şey yayın mekaniği değil, planın kendisidir. Sıfır kesintili yayın düzenleri ve göç ile yayın sırası M16/K08’de ölçüldü; burada sorulan soru, o düzenlerden geri dönmenin kaç adım ve kaç tur olduğudur. Üç senaryo koşturulur, her adımın turu sayılır, dönüşü olmayan noktanın kaçıncı adım olduğu bulunur ve planın prova edilip edilmemesinin ilk koşumda kaç tura mal olduğu ölçülür.
- YS31. Geri alma bir plandır: sıralı adımlar, her adımın bir turu ve sıfır ya da daha çok ön koşulu vardır. Adımlar atlanamaz.
- YS32. Tur, olay anında ödenen süre birimidir; modelde bütün turlar eşit uzunluktadır. Turun dakika karşılığı ortamdan ortama değişir, oran değişmez.
- YS33. Yapılandırma kaydı sürüm tutmaz: üzerine yazılan değer geri getirilemez.
- YS34. Prova, planın olay dışında bir ortamda baştan sona koşturulmasıdır. Kalıcı eksikleri bulur; olay anına bağlı olanları — nöbet, yetki, o gecenin ekibi — bulmaz.
- YS35. Yarıda kalan geri alma karışık durum bırakır: düğümlerin bir kısmı eski, bir kısmı yeni sürümdedir. Bu durumdan çıkmak sabit bir tur ekler.
- YS36. Kurgu, bölgesel ölçüm ağının faturalama servisidir; hatalı bir yayından dönülmektedir. Servis de, aşağıdaki plan ve girişim defterleri de kurgudur.
Planın Üç Senaryosu
Aynı olay üç ayrı geri alma planı doğurur. Yalnız kod değiştiyse plan kısadır. Yayınla birlikte bir yapılandırma değeri de değiştiyse iki adım eklenir. Yayın bir veri göçü taşıdıysa üç adım eklenir. Aşağıdaki yürütücü planı adım adım koşturur, ön koşulu sağlanmayan adımda takılır ve onarım turunu ekler.
// plan.mjs — geri alma bir plan olarak modellenir ve uc senaryoda kosturulur; plan MODELDIR // Bolgesel olcum agi kurgusu: faturalama servisinin hatali yayinindan donus. const ORTAM = { // olay anindaki gercek durum 'onceki-cikti-depoda': true, // saklama kurali icindeki yapi ciktisi duruyor 'saglik-ucu-uyumlu': true, // eski surumun saglik ucu yeni denetimle uyusuyor 'goc-oncesi-yedek': true, // gocten once anlik yedek alinmis 'ayar-onceki-surumu': false, // yapilandirma kaydi surum tutmuyor 'nobetci-yetkisi': false, // geri alma yetkisi yalniz gunduz ekibinde 'geri-goc-betigi': false, // gocun ters adimi yazilmamis }; const ONARIM = { 'ayar-onceki-surumu': 3, 'nobetci-yetkisi': 2, 'geri-goc-betigi': 6 }; // [ad, tur, on kosullar, bu adimdan sonra geri donulebilir mi] const KOD = [ ['kusur dogrulanir', 1, ['saglik-ucu-uyumlu'], true], ['geri alma karari ve yetki', 1, ['nobetci-yetkisi'], true], ['onceki yapi ciktisi secilir', 1, ['onceki-cikti-depoda'], true], ['dugumler eski ciktiya dondurulur', 2, [], true], ['saglik ve tutar dogrulanir', 1, ['saglik-ucu-uyumlu'], true], ]; const AYAR = [ ['ayar onceki degere yazilir', 2, ['ayar-onceki-surumu'], false], ['ayar dugumlere yayilir', 1, [], true], ]; const VERI = [ ['yazma durdurulur', 1, [], true], ['ters goc kosar', 3, ['geri-goc-betigi'], false], ['yazma acilir, sayilar karsilastirilir', 2, ['goc-oncesi-yedek'], true], ]; const SENARYO = { 'yalniz kod': KOD, 'kod + yapilandirma': [...KOD.slice(0, 4), ...AYAR, KOD[4]], 'kod + veri': [...KOD.slice(0, 4), ...VERI, KOD[4]], }; function kostur(plan, provaliMi) { const o = { ...ORTAM }; if (provaliMi) for (const k of Object.keys(ONARIM)) o[k] = true; // prova once buldu, once onardi let tur = 0, ek = 0; const takilan = []; plan.forEach(([ad, t, kosul], i) => { for (const k of kosul) { if (!o[k]) { takilan.push([i + 1, ad, k, ONARIM[k]]); ek += ONARIM[k]; o[k] = true; } } tur += t; }); const d = plan.findIndex(([, , , g]) => !g); return { adim: plan.length, tur, ek, takilan, donus: d < 0 ? '—' : String(d + 1) }; } console.log('senaryo adim provasiz takilma ek tur provasiz provali donusu olmayan adim'); for (const [ad, plan] of Object.entries(SENARYO)) { const y = kostur(plan, false), p = kostur(plan, true); console.log(`${ad.padEnd(19)} ${String(y.adim).padEnd(5)} ${String(y.takilan.length).padEnd(17)} ` + `${String(y.ek).padEnd(7)} ${String(y.tur + y.ek).padEnd(9)} ${String(p.tur + p.ek).padEnd(8)} ${y.donus}`); } console.log(''); console.log('kod + veri, provasiz ilk kosum — adim adim'); const kv = kostur(SENARYO['kod + veri'], false); for (const [no, ad, kosul, onarimTuru] of kv.takilan) { console.log(` adim ${no} takildi: ${ad.padEnd(34)} eksik on kosul: ${kosul} (+${onarimTuru} tur)`); } console.log(` toplam ${kv.adim} adim, ${kv.tur} plan turu, ${kv.ek} onarim turu`); console.log(` ${kv.donus}. adimdan sonra geri donus yok: ters goc veriyi uzerine yazar`);
senaryo adim provasiz takilma ek tur provasiz provali donusu olmayan adim yalniz kod 5 1 2 8 6 — kod + yapilandirma 7 2 5 14 9 5 kod + veri 8 2 8 20 12 6 kod + veri, provasiz ilk kosum — adim adim adim 2 takildi: geri alma karari ve yetki eksik on kosul: nobetci-yetkisi (+2 tur) adim 6 takildi: ters goc kosar eksik on kosul: geri-goc-betigi (+6 tur) toplam 8 adim, 12 plan turu, 8 onarim turu 6. adimdan sonra geri donus yok: ters goc veriyi uzerine yazar
Üç senaryo aynı olaydan doğuyor ve beş, yedi, sekiz adım sürüyor. Adım sayısındaki artış küçük görünür; tur sayısındaki artış öyle değil. Provasız koşumda sekiz turluk bir plan yirmi tura çıkıyor — iki buçuk katı. Aradaki farkın tamamı plan adımlarından değil, adımların ön koşullarından geliyor.
Buradaki asıl sayı, geri almanın yayınla aynı ağırlıkta olmamasıdır. Yayın hattan geçer: aşamalar sıralıdır, ön koşullar hat tarafından sağlanır, her adım daha önce yüzlerce kez koşmuştur. Geri alma ise çoğu kez ilk kez koşar. Aynı sistemin iki yönü arasındaki bu asimetri, üç senaryonun provasız sütununda görünüyor.
Modeldeki altı ön koşulun üçü sağlanmıyor ve üçü de aynı nedenden sağlanmıyor: hiçbiri ileri yönde gerekmiyor. Yapılandırma kaydının geçmiş tutması yayın için gerekmez, ileri yönde son değer yeterlidir. Nöbetçinin geri alma yetkisi yayın için gerekmez, yayını hat yapar. Göçün ters betiği yayın için gerekmez, göç ileri koşar. Üçü de yalnız geri dönüşte gerekir ve yalnız geri dönüşte gereken şey, geri dönülene kadar kimsenin fark etmediği şeydir. Bir ön koşulun eksik olduğunun anlaşıldığı an, çoğunlukla ona en çok ihtiyaç duyulan andır.
Dönüşü Olmayan Nokta
Bir geri alma planında her adım geri alınabilir değildir. Yalnız kod senaryosunda dönüşü olmayan nokta yok: her adım, önceki durumu bozmadan bir sonraki duruma geçiyor; sekizinci turda kararından dönmek isteyen biri yeni sürüme geri yayın yapabilir.
Yapılandırma senaryosunda dönüşü olmayan nokta beşinci adımdır. Yapılandırma kaydı sürüm tutmadığı için önceki değerin üzerine yazmak, o anki değeri kaybetmektir. Kaybolan değer yeni sürümün değeridir ve geri alma başarısız olup yeni sürüme dönülmek istendiğinde o değer artık elde yoktur. Adımın kendisi bir saniye sürer; geri döndürülemezliği süresinden değil, yazdığı yerin geçmiş tutmamasından gelir.
Veri senaryosunda dönüşü olmayan nokta altıncı adımdır. Ters göç, yeni şemada biriken kayıtları eski biçime dönüştürerek üzerine yazar. Bu adımdan sonra planın geri kalanı zorunlu hâle gelir: yedinci ve sekizinci adım koşmazsa sistem ne eski ne yeni durumdadır. Sekiz adımlık planın son üç adımı bu yüzden tek parça sayılır.
Dönüşü olmayan noktanın plan içindeki yeri karar için doğrudan bilgidir. Beşinci ya da altıncı adıma gelmiş bir geri alma, artık “vazgeçilebilir” değildir; o noktadan önce verilmesi gereken karar, geri almanın gerçekten gerekli olup olmadığıdır. Planın hangi adımına kadar ücretsiz olduğunu bilmek, kararın ne zaman verilmesi gerektiğini de söyler.
Prova Edilmemiş Planın Bedeli
Provasız ve provalı sütunlar aynı planları, aynı adım sayısıyla, aynı sırada koşturuyor. Tek fark, ön koşulların olaydan önce mi yoksa olay sırasında mı bulunduğudur. Yalnız kod senaryosunda fark iki tur, veri senaryosunda sekiz tur.
Provasız koşumun adım adım dökümü nerede takıldığını gösteriyor. İkinci adımda nöbetçinin geri alma yetkisi yok: iki tur, başka birine ulaşıp yetkinin açılmasıyla geçiyor. Altıncı adımda göçün ters betiği yazılmamış: altı tur, betiğin olay anında yazılmasıyla geçiyor. İkinci takılmanın yeri kayda değer — dönüşü olmayan noktanın tam üstünde. Betik, geri dönüşün kapandığı adımda yazılıyor ve hiç sınanmadan koşuyor.
Prova bedava değildir. Planın on iki turu prova sırasında da ödenir, ayrıca eksiklerin onarımı da ödenir. Aradaki fark ödemenin ne zaman yapıldığıdır: prova turları olay dışında, seçilmiş bir zamanda, kimseyi bekletmeden geçer. Provasız planın sekiz onarım turu ise olay penceresinin içinde, kusur üretimde koşarken geçer. Aynı iş, farklı fiyatla.
Provanın sınırı da ölçüye girer. Betiğin yazılmamış olması provada bulunur, çünkü kalıcı bir eksiktir. Nöbetçinin yetkisi öyle değildir: prova gündüz koşarsa gündüz ekibinin yetkisiyle geçer ve gece nöbetinde açılan boşluk görünmez.
Kapı: Adım Öncesi Ön Koşul Denetimi
Planın her adımının ön koşulunu adım başlamadan denetlemek bir kapıdır: geçmeyen adım başlatılmaz. Bu kapı da üç sayıyla değerlendirilir. On iki geri alma girişiminden oluşan bir defter iki kipte koşturulur — denetimli ve denetimsiz.
// denetim.mjs — on kosul denetimi bir kapidir; on iki geri alma girisimi iki kipte kosar // [girisim, senaryo, gercekten eksik on kosul, denetimin yanlis "eksik" dedigi] MODELDIR const GIRISIM = [ ['O-01', 'yalniz kod', [], []], ['O-02', 'yalniz kod', ['nobetci-yetkisi'], []], ['O-03', 'kod + yapilandirma', ['ayar-onceki-surumu'], []], ['O-04', 'yalniz kod', [], ['onceki-cikti-depoda']], ['O-05', 'kod + veri', ['geri-goc-betigi'], []], ['O-06', 'yalniz kod', [], []], ['O-07', 'kod + yapilandirma', ['nobetci-yetkisi', 'ayar-onceki-surumu'], []], ['O-08', 'yalniz kod', [], []], ['O-09', 'kod + veri', ['goc-oncesi-yedek'], []], ['O-10', 'yalniz kod', ['nobetci-yetkisi'], []], ['O-11', 'kod + yapilandirma', [], ['ayar-onceki-surumu']], ['O-12', 'kod + veri', [], []], ]; const ONARIM = { 'ayar-onceki-surumu': 3, 'nobetci-yetkisi': 2, 'geri-goc-betigi': 6, 'goc-oncesi-yedek': 4, 'onceki-cikti-depoda': 2 }; const DENETLENEN = new Set(['onceki-cikti-depoda', 'saglik-ucu-uyumlu', 'ayar-onceki-surumu', 'nobetci-yetkisi', 'geri-goc-betigi']); const PROVA_YAKALAR = new Set(['ayar-onceki-surumu', 'geri-goc-betigi', 'onceki-cikti-depoda']); const YARIM = 5; // yarida kalan geri almanin karisik durumdan cikma turu const DENETIM = 1; // plan basina on kosul denetiminin ekledigi tur const say = { tuttu: 0, yalniz: 0, kacirdi: 0, yanlis: 0, yanlisTur: 0, denetimsizEk: 0, denetimliEk: 0 }; for (const [, , eksik, yanlisEksik] of GIRISIM) { const onarim = eksik.reduce((t, k) => t + ONARIM[k], 0); say.denetimsizEk += onarim + (eksik.length ? YARIM : 0); const goren = eksik.filter((k) => DENETLENEN.has(k)); const kacan = eksik.filter((k) => !DENETLENEN.has(k)); const bosuna = yanlisEksik.reduce((t, k) => t + ONARIM[k], 0); say.yanlisTur += bosuna; say.denetimliEk += DENETIM + onarim + (kacan.length ? YARIM : 0) + bosuna; if (goren.length) { say.tuttu += 1; if (goren.every((k) => !PROVA_YAKALAR.has(k))) say.yalniz += 1; } if (kacan.length) say.kacirdi += 1; if (yanlisEksik.length) say.yanlis += 1; } console.log(`girisim : ${GIRISIM.length}`); console.log(`kapinin tuttugu (yarim kalmayi onledigi) : ${say.tuttu}`); console.log(`bunlardan yalniz bu kapinin tuttugu : ${say.yalniz} (provanin yakalayamadigi)`); console.log(`kapinin kacirdigi (denetlenmeyen kosul) : ${say.kacirdi}`); console.log(`kapinin yanlis tuttugu : ${say.yanlis}`); console.log(''); console.log(`denetimsiz kipte olay anina eklenen tur : ${say.denetimsizEk}`); console.log(`denetimli kipte olay anina eklenen tur : ${say.denetimliEk}`); console.log(` bunun denetimin kendisinden geleni : ${GIRISIM.length * DENETIM}`); console.log(` yanlis tutmadan geleni : ${say.yanlisTur}`); console.log(`kapinin net kazanci : ${say.denetimsizEk - say.denetimliEk} tur`); console.log(`girisim basina net kazanc : ${((say.denetimsizEk - say.denetimliEk) / GIRISIM.length).toFixed(2)} tur`);
girisim : 12 kapinin tuttugu (yarim kalmayi onledigi) : 5 bunlardan yalniz bu kapinin tuttugu : 2 (provanin yakalayamadigi) kapinin kacirdigi (denetlenmeyen kosul) : 1 kapinin yanlis tuttugu : 2 denetimsiz kipte olay anina eklenen tur : 52 denetimli kipte olay anina eklenen tur : 44 bunun denetimin kendisinden geleni : 12 yanlis tutmadan geleni : 5 kapinin net kazanci : 8 tur girisim basina net kazanc : 0.67 tur
Kapı on iki girişimin beşinde yarıda kalan bir geri almayı önledi. Ama bu beşin üçünü prova da yakalardı: kalıcı eksiklerdi, planı bir kez baştan sona koşturmak yeterdi. Kapının yalnız kendisinin tuttuğu iki girişim, nöbetçi yetkisinin o gece eksik olduğu girişimlerdir — prova gündüz koştuğu için görünmeyen, olay anına bağlı eksik. Marjinal değer beşte değil, ikidedir.
Kapı bir girişimi kaçırdı: göç öncesi yedeğin alınmamış olması denetim listesinde yok. Denetim listesi kendisi bir kod parçasıdır ve neyi denetlediği kadar neyi denetlemediği de sayılmalıdır. İki girişimde ise kapı yanlış tuttu — sağlanmış bir ön koşulu eksik sandı ve beş turluk bir onarımı boşuna ödetti.
Kapının eklediği süre bu defterde ayrı bir satırdır: her girişimde bir tur, on iki girişimde on iki tur. Bu süre, kusurun üretimde koşmaya devam ettiği bir pencerede ödeniyor ve girişimlerin yedisinde hiçbir eksik bulmadan geçiyor. Yanlış tutmanın beş turu da aynı pencerede. Kapının brüt kazancı yirmi beş tur, kendi maliyeti on yedi tur.
Net kazanç elli iki tura karşı kırk dört tur, girişim başına üçte iki tur. Bu ince bir farktır ve kapının kendi maliyeti — on iki tur — kazancın üstündedir. Kapıyı ayakta tutan şey ortalama değil, dağılımdır: kaçırılan girişimlerde bedel beş turluk karışık durumdur ve bu bedel olay penceresinin içinde, kusur koşarken ödenir. Kapının savunulabilir tek biçimi, denetim listesinin prova ile bölüşülmesidir: kalıcı eksikler provada, olay anına bağlı olanlar kapıda.
Özet
- Aynı olay üç plan doğurdu: yalnız kod beş adım, kod ile yapılandırma yedi adım, kod ile veri sekiz adım; provasız toplam süreleri sırasıyla sekiz, on dört ve yirmi tur oldu.
- Dönüşü olmayan nokta yalnız kod senaryosunda yok, yapılandırma senaryosunda beşinci, veri senaryosunda altıncı adımdır; o adımdan sonra planın kalanı zorunlu hâle gelir.
- Provasız koşum iki adımda takıldı ve sekiz onarım turu ekledi; ikinci takılma dönüşü olmayan noktanın hemen üstünde, ters göç betiğinin olay anında yazıldığı adımdaydı.
- Prova aynı işi ödetir, farklı zamanda: on iki plan turu olay dışında geçer, sekiz onarım turu ise kusur üretimde koşarken geçer.
- Ön koşul denetimi kapısı on iki girişimin beşini tuttu, ikisini yalnız kendisi tuttu, birini kaçırdı, ikisini yanlış tuttu; net kazancı sekiz tur, kendi maliyeti on iki turdu.
Sonraki Adım
Üç senaryodan ikisinde dönüşü olmayan nokta vardı ve ikisi de veriyle ilgiliydi. Kod geri alınabilir, yapılandırma sürümlenirse geri alınabilir; şema değişikliği için bu o kadar sade değildir. Kimi göç türü tam olarak geri alınabilir, kimisi çalışır görünüp veriyi eksik geri getirir, kimisinden dönüş yoktur. Sonraki ders göç türlerini geri alınabilirlik ekseninde sıralar, genişlet–taşı–daralt düzenini adım adım koşturur ve her adımda eski ile yeni sürümün aynı anda çalışıp çalışamadığını sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.