İçeriğe geç
academia.sh

Ders 13 / 14

Yayımlama

Dokuz yayım girişimi üzerine yazılabilir bir kayıtta 9 kabul ve 2 sessiz değişiklik, değiştirilemez bir kayıtta 7 kabul ve 2 red üretir; aynı kilit dosyası ilk kayıtta 2 ayrı kurulum verir ve özet yazan bir kilit bu iki uyuşmazlığın ikisini de yakalayarak kurulumu durdurur.

İçindekiler

Önceki ders dağıtımı üretti ve içeriğini bir özetle adlandırdı. O özet üretim tarafında hesaplanan bir sayıydı ve orada kaldı; kurulan tarafın ondan haberi yoktu.

Paket bir paket kaydına (package registry) gönderildiğinde bu düzen değişir. Kurulan taraf artık içeriği değil, adı ister: “olcum paketinin 1.2 sürümü”. Adın karşılığını kayıt verir. Bu dersin sorusu buradan doğar: aynı ad iki ayrı içeriği taşıyabilir mi, ve taşıyabiliyorsa kilit dosyasının yazdığı sürüm numarası neyi garanti eder?

Kayıt Ne Saklar

Paket kaydı, (ad, sürüm) çiftinden bir dağıtıma giden bir eşlemedir. Bu kurs kayıt ürün adı yazmaz; kayıt burada tek bir sözlükle modellenir ve üzerinde tek bir işlem tanımlanır: yayımla. Model gerçek bir kayda bağlanmaz, hiçbir şey gönderilmez ve hiçbir paket indirilmez.

Sürüm işaretlemenin kendisi — etiketleme ve anlamlı sürümleme — Sürüm Kontrolüne Giriş kursunda kurulmuştu ve burada tekrarlanmaz. Bu ders sürüm numarasının nasıl seçileceğini sormaz; seçilmiş bir numaranın ne kadar bağlayıcı olduğunu sorar.

İki İlke

Yayımla işleminin (ad, sürüm) çifti daha önce kullanılmışsa ne yapacağı bir ilke sorusudur ve iki yanıtı vardır.

Üzerine yazılabilir kayıt, yeni gövdeyi eskisinin yerine koyar. Gönderim her zaman başarılıdır. Değiştirilemez kayıt, aynı çifte ayrı bir gövde geldiğinde gönderimi reddeder. Aynı gövdenin yeniden gönderilmesini reddetmez — o gönderim kaydı zaten değiştirmez.

Ayrımın tam yeri budur: değiştirilemezlik yeniden gönderimi değil, ayrı içerikle yeniden gönderimi yasaklar. Bir yayım akışında ikisi yan yana bulunabilir ve ölçüm ikisini de içerir.

Ölçüm dokuz yayım girişimi tanımlar. Üçü ortak kurgunun kilit dosyasındaki sürümleri ilk kez yayımlar, biri daha eski bir sürümü yayımlar, biri aynı gövdeyi yeniden gönderir, ikisi aynı sürüme ayrı gövde gönderir, biri aynı gövdeyi bir kez daha gönderir, biri yeni bir sürüm açar. İki zaman noktası okunur: beşinci girişimden sonra t1, dokuzuncudan sonra t2.

Ölçümün varsayımları:

  • KY22 — Kilit dosyası ortak tanımın “en yeni” çözümlemesinin sonucudur: olcum 1.2, ortak 3.2, rapor 1.1. Kilidin içeriği ölçüm boyunca değişmez.
  • KY23 — Dağıtımın içeriği tek bir gövde dizgisiyle temsil edilir; özeti kısaltılmış sekiz onaltılık basamaktır ve iki özetin eşitliği içeriğin eşitliği olarak okunur.
  • KY24 — Kurulum, kilit dosyasındaki üç sürümün kayıttaki özetlerini okumaktır. Kurulumun başka hiçbir yan etkisi modellenmez.
  • KY25t1 ve t2, aynı kilit dosyasıyla yapılan iki ayrı kurulumdur. Aradaki tek fark, kayda bu sürede gelen yayım girişimleridir.
  • KY26 — Özet yazan kilit, kurulum anında beklenen ve gelen özeti karşılaştırır; uyuşmazlık bulursa kurulum durur. Uyuşmazlığı düzeltmeye çalışmaz.
  • KY27 — Geri çekme, sürümü çözümlemeye kapatır ama kayıttaki içeriğine dokunmaz; kilit dosyası sürümü doğrudan istediği için çözümlemeyi hiç çalıştırmaz.
  • KY28 — Süre ölçülmez, gerçek kayda gönderim yapılmaz. Sayılan şey kabul, red, uyuşmazlık ve ayrı kurulum sayısıdır.

Ölçüm

"""Yayimlama: ayni ad iki ayri icerigi tasiyabilir mi."""

import hashlib

KILIT = {"olcum": (1, 2), "ortak": (3, 2), "rapor": (1, 1)}
DEPO = {"rapor": [(0, 9), (1, 0), (1, 1)]}
BILDIRIM = {"rapor": ((1, 0), (2, 0))}
GERI_CEKILEN = {("rapor", (1, 1))}

GIRISIMLER = [
    ("rapor", (1, 0), "rapor-govde-0"),
    ("olcum", (1, 2), "olcum-govde-1"),
    ("ortak", (3, 2), "ortak-govde-1"),
    ("rapor", (1, 1), "rapor-govde-1"),
    ("olcum", (1, 2), "olcum-govde-1"),
    ("rapor", (1, 1), "rapor-govde-2"),
    ("olcum", (1, 2), "olcum-govde-2"),
    ("ortak", (3, 2), "ortak-govde-1"),
    ("olcum", (2, 0), "olcum-govde-3"),
]
T1 = 5
ILKELER = (("üzerine yazılabilir", False), ("değiştirilemez", True))


def ozet(metin):
    return hashlib.sha256(metin.encode()).hexdigest()[:8]


def yayimla(girisimler, degistirilemez):
    """Paket kaydi modeli: (ad, surum) -> dagitim ozeti."""
    kayit, kabul, red, cakisma = {}, 0, 0, []
    for paket, surum, govde in girisimler:
        anahtar, o = (paket, surum), ozet(govde)
        varsa = kayit.get(anahtar)
        if varsa is not None and varsa != o:
            cakisma.append(f"{paket} {surum[0]}.{surum[1]}")
            if degistirilemez:
                red += 1
                continue
        kayit[anahtar] = o
        kabul += 1
    return kayit, kabul, red, cakisma


def kurulum(kayit):
    """Kilit dosyasindaki surumler kayittan okunur."""
    return {p: kayit[(p, s)] for p, s in KILIT.items()}


print(f"{'ilke':<20s} {'kabul':>5s} {'red':>4s} {'t1 kurulum':>28s}"
      f" {'t2 kurulum':>28s} {'ayrı':>5s}")
for ad, kural in ILKELER:
    b = kurulum(yayimla(GIRISIMLER[:T1], kural)[0])
    kayit, kabul, red, cakisma = yayimla(GIRISIMLER, kural)
    g = kurulum(kayit)
    d1 = " ".join(b[p] for p in sorted(KILIT))
    d2 = " ".join(g[p] for p in sorted(KILIT))
    print(f"{ad:<20s} {kabul:5d} {red:4d} {d1:>28s} {d2:>28s}"
          f" {len({d1, d2}):5d}")
print(f"çakışan gönderim: {', '.join(yayimla(GIRISIMLER, True)[3])}")

print()
print(f"{'kilit biçimi':<15s} {'ilke':<20s} {'uyuşmazlık':>10s} "
      f"{'yakalanan':>9s} {'kurulum':>9s} {'ayrı içerik':>12s}")
for kb, ozetli in (("yalnız sürüm", False), ("sürüm ve özet", True)):
    for ad, kural in ILKELER:
        b = kurulum(yayimla(GIRISIMLER[:T1], kural)[0])
        g = kurulum(yayimla(GIRISIMLER, kural)[0])
        uyusmaz = sum(1 for p in KILIT if b[p] != g[p])
        yakalanan = uyusmaz if ozetli else 0
        durdu = yakalanan > 0
        kurulan = ({tuple(sorted(b.items()))} if durdu
                   else {tuple(sorted(b.items())), tuple(sorted(g.items()))})
        print(f"{kb:<15s} {ad:<20s} {uyusmaz:10d} {yakalanan:9d} "
              f"{'duruyor' if durdu else 'sürüyor':>9s} {len(kurulan):12d}")

print()


def coz(paket, geri_cekmeyi_uygula):
    alt, ust = BILDIRIM[paket]
    return [s for s in DEPO[paket] if alt <= s < ust
            and not (geri_cekmeyi_uygula and (paket, s) in GERI_CEKILEN)][-1]


kayit = yayimla(GIRISIMLER, True)[0]
print(f"{'kurulum yolu':<18s} {'geri çekmeden önce':>20s} {'sonra':>20s} "
      f"{'ayrı':>5s}")
for ad, secici in (("çözümleme ile", lambda gc: coz("rapor", gc)),
                   ("kilit dosyasıyla", lambda gc: KILIT["rapor"])):
    o = [f"{'.'.join(map(str, secici(gc)))}·{kayit[('rapor', secici(gc))]}"
         for gc in (False, True)]
    print(f"{ad:<18s} {o[0]:>20s} {o[1]:>20s} {len(set(o)):5d}")
ilke                 kabul  red                   t1 kurulum                   t2 kurulum  ayrı
üzerine yazılabilir      9    0   3d3f4bcd 69832227 acf4bf32   d032978b 69832227 3c8049dd     2
değiştirilemez           7    2   3d3f4bcd 69832227 acf4bf32   3d3f4bcd 69832227 acf4bf32     1
çakışan gönderim: rapor 1.1, olcum 1.2

kilit biçimi    ilke                 uyuşmazlık yakalanan   kurulum  ayrı içerik
yalnız sürüm    üzerine yazılabilir           2         0   sürüyor            2
yalnız sürüm    değiştirilemez                0         0   sürüyor            1
sürüm ve özet   üzerine yazılabilir           2         2   duruyor            1
sürüm ve özet   değiştirilemez                0         0   sürüyor            1

kurulum yolu         geri çekmeden önce                sonra  ayrı
çözümleme ile              1.1·acf4bf32         1.0·660f7f84     2
kilit dosyasıyla           1.1·acf4bf32         1.1·acf4bf32     1

Dokuz Girişim, İki Red

Üst tablo iki ilkeyi aynı akış üzerinde karşılaştırıyor.

Üzerine yazılabilir kayıt dokuz girişimin dokuzunu da kabul ediyor: 9 kabul, 0 red. Hiçbir gönderim başarısız olmuyor, hiçbir uyarı çıkmıyor. Buna karşın kaydın içeriği değişiyor ve bu değişim t1 ile t2 sütunlarında görünüyor: olcum 1.2 özeti 3d3f4bcd iken d032978b oluyor, rapor 1.1 özeti acf4bf32 iken 3c8049dd oluyor. Aynı kilit dosyası 2 ayrı kurulum veriyor.

Değiştirilemez kayıt aynı akışta 7 kabul, 2 red üretiyor. Reddedilen ikisi rapor 1.1 ve olcum 1.2; ikisi de daha önce başka bir gövdeyle yayımlanmış çiftler. Aynı gövdenin yeniden gönderildiği iki girişim ise kabul ediliyor — beşinci ve sekizinci girişimler kaydı değiştirmedikleri için reddedilecek bir şey yok. t1 ve t2 sütunları birebir aynı: 1 ayrı kurulum.

Sayının okunuşu şudur: 9 kabul, 0 red görüntüsü bir sağlık göstergesi değildir. İki kayıt da aynı dokuz girişimi aldı; biri iki çakışmayı sesli, öbürü sessiz işledi. Sessiz olanın raporu daha temiz görünüyor ve tam olarak bu yüzden daha az bilgi taşıyor.

Değiştirilemezliğin verdiği güvence tek cümleyle yazılabilir: bir ad ve sürüm çifti, ömrü boyunca en fazla bir içeriği adlandırır. Bu güvence olmadan sürüm numarası bir tanımlayıcı değil, yalnızca bir etikettir; aynı etiket iki ayrı kutuya yapıştırılabilir.

Aynı gövdenin iki kez kabul edilmesi bu güvenceyle çelişmez ve pratikte gereklidir. Bir gönderim yarıda kesilebilir, sonucu gönderen tarafa ulaşmayabilir; gönderen o zaman aynı gövdeyi yeniden gönderir. Değiştirilemez kayıt bunu reddetseydi, gönderen tarafın gönderimin gerçekleşip gerçekleşmediğini önce sorması gerekirdi. Kural içeriğe bakarak kurulduğu için ikinci gönderim kaydı değiştirmez ve reddedilecek bir şey doğmaz — ölçümdeki 7 kabul sayısının içinde bu iki gönderim de vardır. Yasaklanan işlem “yeniden göndermek” değil, kaydı değiştirmektir.

Sürüm Numarasının Taşıdığı İki Söz

Bir sürüm numarası iki ayrı söz verir ve ikisi sık sık tek bir söz sanılır.

Birinci söz uyumlulukla ilgilidir: numaranın hangi bölümünün arttığı, değişikliğin geriye dönük uyumlu olup olmadığını bildirir. Bu söz Sürüm Kontrolüne Giriş kursunun etiketleme dersinde kuruldu ve burada tekrarlanmaz.

İkinci söz kimlikle ilgilidir: numara tek bir içeriği adlandırır. Bu ders yalnız ikinci sözü ölçer, ve ölçüm gösteriyor ki bu söz numaranın kendisinden gelmez; kaydın ilkesinden gelir. Üzerine yazılabilir bir kayıtta numara birinci sözü verebilir ama ikincisini veremez.

İkisinin bağımsız olduğu, ölçümün üst tablosunda doğrudan görülüyor. Reddedilen iki gönderim de mevcut bir çifte ayrı gövde göndermeye çalışıyor; ikisinin de uyumluluk sözüyle ilgisi yok. Gövde tümüyle uyumlu bir düzeltme bile olsa red aynı olurdu, çünkü denetlenen şey uyumluluk değil kimliktir.

Reddin yayımlayan tarafa ödettiği bedel de bellidir: değişiklik yayımlanacaksa yeni bir sürüm numarası açılmak zorundadır. Ölçümün dokuzuncu girişimi tam olarak bunu yapıyor ve olcum 2.0 olarak kabul ediliyor. Değiştirilemezlik bir yasak değil, bir yönlendirmedir: düzeltmeyi engellemez, düzeltmenin adlandırılmasını zorunlu kılar. Bunun karşılığında kurulan taraf, elindeki numaranın anlamının zamanla değişmediğini bilir.

Kilidin Yazdığı Şey

Orta tablo, kurulan tarafın kendini bu duruma karşı ne kadar koruyabildiğini ölçüyor.

Yalnız sürüm yazan kilit, üzerine yazılabilir kayıtta 2 uyuşmazlık karşısında 0 yakalıyor. Kurulum sürüyor ve 2 ayrı içerik kuruluyor. Kilit dosyası burada işini yapmış sayılır — istenen sürümler kuruldu — ama kurduğu şey iki ayrı koşumda iki ayrı şeydi. Kilit çözümlemeyi tekleştirdi, içeriği tekleştirmedi.

Sürüm ve özet yazan kilit, aynı kayıtta 2 uyuşmazlığın 2’sini yakalıyor ve kurulum duruyor. Kurulan ayrı içerik sayısı 1’e iniyor, çünkü ikinci kurulum hiç tamamlanmıyor. Burada kazanılan şey bir kurulumun başarısı değil, başarısızlığın görünürlüğüdür: kayıt sessiz kaldığında kilit sesli olur.

Alt iki satır ilkenin doğru kurulduğu durumu gösteriyor: değiştirilemez kayıtta uyuşmazlık 0, yakalanan 0, kurulum sürüyor, ayrı içerik 1. Özet yazmanın burada bir maliyeti yok ve bir kazancı da görünmüyor — çünkü yakalayacak bir şey yok.

Buradan iki ayrı güvencenin bağımsız olduğu çıkar. Değiştirilemezlik kaydın verdiği bir güvencedir ve kurulan taraf onu doğrulayamaz. Özet ise kurulan tarafın kendi doğrulamasıdır ve kaydın ilkesinden bağımsız çalışır. İkisi birlikte kurulduğunda kurulan taraf kayda güvenmek zorunda kalmaz; yalnız birincisi varsa güvenmek zorundadır, yalnız ikincisi varsa güvenmez ama sık sık durur.

Geri Çekme Silme Değildir

Alt tablo üçüncü bir işlemi ölçüyor. Bir sürüm yayımlandıktan sonra kullanılmaması gerektiği anlaşılabilir. Geri çekme, sürümü çözümlemeye kapatır ama kayıttaki içeriğine dokunmaz.

Ölçüm ikisini ayırıyor. Çözümleme ile kurulan taraf, geri çekmeden önce rapor 1.1 sürümünü ve acf4bf32 özetini alıyor; sonra rapor 1.0 sürümünü ve 660f7f84 özetini alıyor. 2 ayrı sürüm. Kilit dosyasıyla kurulan taraf ise iki durumda da 1.1·acf4bf32 alıyor: 1.

Fark, kilit dosyasının çözümlemeyi hiç çalıştırmamasından gelir. Geri çekme çözümlemenin aday listesini değiştirir; kilit dosyası aday listesi kullanmaz, doğrudan sürümü ister ve kayıt onu vermeye devam eder. Bu, kilidin hem gücü hem sınırıdır: geri çekilmiş bir sürümü kullanmayı sürdürür ve bunu sessizce yapar.

Silme ayrı bir işlemdir ve ayrı bir sonuç verir: silinmiş bir sürümde kilit dosyasıyla kurulum da başarısız olur. Üç işlem — üzerine yazma, geri çekme, silme — üç ayrı sonuç üretir, ve yalnız ikisi kurulan tarafa haber verir.

Üçünü yan yana koymak, kaydın kurulan tarafa ne borçlu olduğunu tanımlar. Üzerine yazma içeriği değiştirir ve hiçbir şey söylemez; kurulan taraf ancak kendi tuttuğu özetle fark eder. Geri çekme içeriği değiştirmez ve yalnız yeni çözümlemelere görünür; kilitli kurulum etkilenmez. Silme içeriği ortadan kaldırır ve her iki yolu da durdurur. Sıralama bir sertlik sırası değil, bir görünürlük sırasıdır: en sessiz işlem en çok zarar veren işlemdir, çünkü ötekilerin ikisinde de kurulan taraf bir yanıt alır.

Geri çekmenin sessiz kaldığı yerin de bir adı vardır. Kilit dosyasını yenilemeyen bir proje geri çekilmiş sürümü kullanmayı sürdürür ve bunu bir hata iletisi olmadan yapar; geri çekme kararı ancak kilit yenilendiğinde o projeye ulaşır. Kilit, çözümlemenin sonucunu donduran bir karardır — ve dondurduğu şeye sonradan verilen kararları da dışarıda bırakır.

Özet

  • Paket kaydı (ad, sürüm) çiftinden bir dağıtıma giden eşlemedir; üzerine yazılabilir ve değiştirilemez olmak üzere iki ilkeyle kurulabilir.
  • Aynı dokuz girişim ilk kayıtta 9 kabul, 0 red, ikincisinde 7 kabul, 2 red verir; değiştirilemezlik yeniden gönderimi değil, ayrı içerikle yeniden gönderimi yasaklar.
  • Aynı kilit dosyası üzerine yazılabilir kayıtta 2 ayrı kurulum, değiştirilemez kayıtta 1 verir; sürüm numarası tek başına içeriği belirlemez.
  • Yalnız sürüm yazan kilit 2 uyuşmazlığın 0’ını, özet de yazan kilit 2’sini yakalar ve kurulumu durdurur; kaydın ilkesi ile kurulan tarafın doğrulaması bağımsız güvencelerdir.
  • Geri çekme çözümlemeyi etkiler, kilidi etkilemez: çözümleme ile kurulan taraf 2 ayrı sürüm, kilitle kurulan taraf 1 görür.

Sonraki Adım

Yayımlanmış paket kurulan tarafa kodu taşır. Kodun nasıl kullanılacağını taşımaz. O bilgi belgeden gelir, ve belge iki yoldan üretilebilir: elle yazılarak ya da kaynaktan üretilerek. İki yol arasındaki fark bu kursun bütün derslerinde sorulan soruyla ölçülebilir. Son ders bunu sorar: kaynaktan belge üretimi hangi sonucu tekleştirir, hangisini tekleştirmez, ve tekleştirmediği yerde neyin yerini alamaz?

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat