İçeriğe geç
academia.sh

Ders 04 / 14

Sürüm Yönetimi

Aynı bildirim üç kurgu yorumlayıcı sürümünde 2 ayrı sürüm kümesi verir; bir yorumlayıcıda üretilmiş kilit dosyalarının dokuz kurulumundan 6'sı kabul edilip 3'ü reddedilir ve aynı kilit sabit yorumlayıcıda 1 ayrı sonuç verirken üç yorumlayıcıda bir ret üretir.

İçindekiler

Önceki üç ders aynı bildirimin kaç ayrı sürüm kümesi verdiğini üç ayrı eksende ölçtü: yalıtım sınırı, çözümleme stratejisi ve çözümleyicinin kendisi. Üçünde de yazılmamış bir varsayım vardı — tek bir yorumlayıcı. Paket sürümleri karşılaştırılırken hepsinin aynı yorumlayıcıda kurulabildiği kabul edildi.

Bu ders o varsayımı ölçüme sokar. Sorusu iki parçalıdır: aynı proje, ayrı yorumlayıcı sürümlerinde kaç ayrı sonuç veriyor, ve bir yorumlayıcıda üretilmiş kilit dosyası bir başkasında ne yapıyor? İkinci parçanın yanıtı, kilidin ne tür bir güvence olduğunu kesinleştirecek.

Yorumlayıcı da Bir Bağımlılıktır

Bir proje kendi bildirimini yazarken paketlerini sayar; yorumlayıcıyı saymayı çoğu zaman atlar. Oysa yorumlayıcı da kurulan bir şeydir, sürümü vardır ve o sürüm değiştiğinde projenin karşılaştığı davranış değişebilir.

Bu ders gerçek sürüm numarası yazmaz. Yorumlayıcılar kurgu etiketlerle anılır: Y1, Y2, Y3. Etiketlerin sırası bir zaman sırasıdır — Y1 en eski, Y3 en yeni — ve bunun dışında hiçbir şey ima etmez. Paketlerin sürümleri de önceki üç dersteki gibi kurgudur.

Ölçümün kurduğu ilişki basit bir tablodur: her paket sürümü, hangi yorumlayıcı sürümlerinde kurulabildiğini bildirir. Bu bir kurgu değil, gerçek bir kısıttır; bir paket sürümü belli bir dil düzeyine göre yazılmıştır ve o düzeyi karşılamayan bir yorumlayıcıda ya kurulamaz ya çalışmaz. Kurguda bu ilişki bir küme olarak yazılmıştır ve modellenmiştir; hiçbir ürün adı geçmez.

Bunun doğrudan sonucu şudur: yorumlayıcı, aday havuzunu daraltır. Bildirim değişmemiştir, depo değişmemiştir, strateji değişmemiştir; ama aynı aralıktan seçilebilecek sürümlerin listesi yorumlayıcıya göre kısalır. Çözümleme aynı kuralı ayrı bir havuza uygular ve ayrı bir küme döndürür.

Ortamın Yorumlayıcıya Bağlılığı

İlk derste sanal ortamın yorumlayıcıyı çoğaltmadığı, ona bağlandığı söylenmişti. Buradaki ölçüm o cümlenin bedelini gösterir.

Bir ortam hangi yorumlayıcı üzerinde kurulduysa onunla anlamlıdır. Yorumlayıcı sürümü değiştiğinde ortam taşınmaz: sitedeki paketlerin bir bölümü yeni yorumlayıcı için üretilmemiş olabilir, ve içe aktarma yolu da yorumlayıcı sürümüne göre adlandırılır. Geçiş işlemi bu yüzden bir yükseltme değil, yeni bir ortam kurmaktır — ve yeni ortamda ne kurulacağı yeniden çözümlenir.

Aynı şey kilit dosyası için de geçerli midir? Kilit tam sürümler yazar ve çözümleme yapmaz; öyleyse yeni yorumlayıcıda da aynı kümeyi kurmalıdır. Ölçümün sınadığı sav budur ve yanıt tek kelimeyle verilemez.

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

  • OB37 — Depo, bildirim ve aralık kuralı ortak tanımdan birebir alınır; ders ikisinin de davranışını değiştirmez. Eklenen tek şey uyum tablosudur.
  • OB38 — Üç yorumlayıcı sürümü kurgudur ve Y1, Y2, Y3 etiketleriyle anılır. Gerçek sürüm numarası yazılmaz.
  • OB39 — Uyum tablosu kurgudur ve kâhinin parçasıdır: her paket sürümünün hangi yorumlayıcılarda kurulabildiğini biz yazdık, bu yüzden her satırın doğru sonucu ölçmeden bilinir.
  • OB40 — Uyum bir ikili karardır: bir sürüm bir yorumlayıcıda ya kurulabilir ya kurulamaz. Kısmi çalışma ya da uyarıyla kurulum modellenmez.
  • OB41 — Çözümleme aday havuzunu önce bildirimle, sonra uyum tablosuyla daraltır. Sıra sonucu değiştirmez; iki süzgeç de kesişimi alır.
  • OB42 — Strateji bu derste sabittir: en yeni uygun sürüm. Strateji ekseni önceki iki derste ölçüldü ve burada tekrarlanmaz.
  • OB43 — Paketler bu derste birbirini gerektirmez; gerek ekseni önceki derste ölçüldü. Ölçülen tek yeni eksen yorumlayıcıdır.
  • OB44 — Kilit dosyası tam sürümler yazar ve çözümleme yapmaz. Kilitle kurulum, yazılan her sürümün hedef yorumlayıcıda kurulabilmesini gerektirir.
  • OB45 — Kurulum reddi bir hata değil, ölçümün bir sonucudur ve tabloda ret olarak sayılır. Reddedilen kurulum hiçbir ayrı sonuç üretmez.
  • OB46 — Her yorumlayıcının kilidi kendi çözümlemesinden üretilir; dokuz kurulum, üç kilidin üç yorumlayıcıya uygulanmasıdır.
  • OB47 — Yorumlayıcı sürümleri arasında geçiş, ortamın yeniden kurulmasıdır; eski site taşınmaz ve modelde de taşınmaz.
  • OB48Gerçek kurulum yapılmaz, gerçek paket indirilmez, gerçek yorumlayıcı çağrılmaz. Yorumlayıcı bir etiket, kurulum bir sözlüktür.
  • OB49 — Süre ölçülmez. Sayılan şey ayrı sürüm kümesi, kabul ve ret sayısıdır.
  • OB50 — Ölçüm tek koşumdur, belirlenimcidir ve kurguda rastgelelik yoktur.

Ölçüm

"""Yorumlayici surumleri: ayni proje, ayni bildirim, kac ayri sonuc."""

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

# Kurgu yorumlayici surumleri; gercek surum numarasi degildir.
YORUMLAYICILAR = ("Y1", "Y2", "Y3")

# Paket surumu -> destekledigi yorumlayicilar
UYUM = {
    ("olcum", (1, 0)): {"Y1", "Y2"}, ("olcum", (1, 1)): {"Y1", "Y2"},
    ("olcum", (1, 2)): {"Y2", "Y3"}, ("olcum", (2, 0)): {"Y3"},
    ("ortak", (3, 0)): {"Y1", "Y2"}, ("ortak", (3, 1)): {"Y1", "Y2", "Y3"},
    ("ortak", (3, 2)): {"Y2", "Y3"}, ("ortak", (4, 0)): {"Y3"},
    ("rapor", (0, 9)): {"Y1"}, ("rapor", (1, 0)): {"Y1", "Y2"},
    ("rapor", (1, 1)): {"Y2", "Y3"},
}


def uygun(paket, yorumlayici):
    alt, ust = BILDIRIM[paket]
    return [s for s in DEPO[paket]
            if alt <= s < ust and yorumlayici in UYUM[(paket, s)]]


def coz(yorumlayici, strateji="en yeni"):
    secim = {}
    for paket in sorted(BILDIRIM):
        adaylar = uygun(paket, yorumlayici)
        if not adaylar:
            return None
        secim[paket] = adaylar[-1] if strateji == "en yeni" else adaylar[0]
    return secim


def kilit(secim):
    return dict(secim)


def kur(kilit_dosyasi, yorumlayici):
    """Kilit her surumu tam yazar; yorumlayici desteklemiyorsa kurulum reddedilir."""
    if all(yorumlayici in UYUM[(p, s)] for p, s in kilit_dosyasi.items()):
        return dict(kilit_dosyasi)
    return None


def yazim(secim):
    if secim is None:
        return f"{'reddedildi':>23s}"
    return " ".join(f"{'.'.join(map(str, secim[p])):>7s}" for p in PAKETLER)


def kisa(secim):
    if secim is None:
        return f"{'ret':>12s}"
    return f"{'/'.join('.'.join(map(str, secim[p])) for p in PAKETLER):>12s}"


def anahtar(secim):
    return tuple(sorted(secim.items()))


print(f"{'bildirimle çözümleme':<26s} {'olcum':>7s} {'ortak':>7s} {'rapor':>7s}")
cozumler = {}
for y in YORUMLAYICILAR:
    cozumler[y] = coz(y)
    print(f"{'yorumlayıcı ' + y:<26s} " + yazim(cozumler[y]))
print(f"aynı bildirim, üç yorumlayıcı: {len({anahtar(s) for s in cozumler.values()})} "
      f"ayrı sürüm kümesi")

print()
print(f"{'kilit üretildiği yorumlayıcı':<30s} " +
      " ".join(f"{'kurulum ' + y:>12s}" for y in YORUMLAYICILAR))
kabul, kumeler = 0, []
for uretim in YORUMLAYICILAR:
    k = kilit(cozumler[uretim])
    hucre = []
    for hedef in YORUMLAYICILAR:
        s = kur(k, hedef)
        kabul += s is not None
        if s is not None:
            kumeler.append(anahtar(s))
        hucre.append(kisa(s))
    print(f"{'kilit ' + uretim + ' üzerinde üretildi':<30s} " + " ".join(hucre))
print(f"dokuz kurulum: {kabul} kabul, {9 - kabul} ret; kabul edilenlerde "
      f"{len(set(kumeler))} ayrı sürüm kümesi")

print()
k2 = kilit(cozumler["Y2"])
sabit = [kur(k2, "Y2") for _ in range(3)]
gezen = [kur(k2, y) for y in YORUMLAYICILAR]
for ad, kurulumlar in (("aynı kilit, Y2'de üç kurulum", sabit),
                       ("aynı kilit, üç yorumlayıcıda", gezen)):
    olan = [s for s in kurulumlar if s is not None]
    print(f"{ad:<30s} {len({anahtar(s) for s in olan})} ayrı sonuç, "
          f"{len(kurulumlar) - len(olan)} ret")
bildirimle çözümleme         olcum   ortak   rapor
yorumlayıcı Y1                 1.1     3.1     1.0
yorumlayıcı Y2                 1.2     3.2     1.1
yorumlayıcı Y3                 1.2     3.2     1.1
aynı bildirim, üç yorumlayıcı: 2 ayrı sürüm kümesi

kilit üretildiği yorumlayıcı     kurulum Y1   kurulum Y2   kurulum Y3
kilit Y1 üzerinde üretildi      1.1/3.1/1.0  1.1/3.1/1.0          ret
kilit Y2 üzerinde üretildi              ret  1.2/3.2/1.1  1.2/3.2/1.1
kilit Y3 üzerinde üretildi              ret  1.2/3.2/1.1  1.2/3.2/1.1
dokuz kurulum: 6 kabul, 3 ret; kabul edilenlerde 2 ayrı sürüm kümesi

aynı kilit, Y2'de üç kurulum   1 ayrı sonuç, 0 ret
aynı kilit, üç yorumlayıcıda   1 ayrı sonuç, 1 ret

İki Küme, Üç Yorumlayıcı

Üst tablo aynı bildirimi üç yorumlayıcıda çözüyor ve 2 ayrı sürüm kümesi veriyor.

Y1 satırı 1.1 / 3.1 / 1.0 veriyor. Üçünün de en yenisi değil bunlar; olcum 1.2, ortak 3.2 ve rapor 1.1 bu yorumlayıcıda kurulamıyor ve havuzdan düşüyor. Strateji hâlâ “en yeni uygun sürüm”; değişen, neyin uygun sayıldığı. Y2 ve Y3 ise aynı kümeyi veriyor: 1.2 / 3.2 / 1.1.

İki gözlem buradan çıkar. Birincisi, yorumlayıcı ekseni kendi başına bir ayrı sonuç üretir: bildirime, stratejiye ve depoya dokunmadan iki kurulum elde edildi. İkincisi, sayı yorumlayıcı sayısıyla aynı değil. Üç yorumlayıcı iki küme verdi çünkü Y2 ile Y3 aynı adaylara izin veriyor. Ayrı sonuç sayısı, ortam sayısının değil uyum tablosunun işlevidir.

Y1 satırının bir yan sonucu daha var. O yorumlayıcıda çalışan bir proje, sonraki sürümlerde düzeltilmiş kusurları taşıyan paketleri hiç görmez; bildirimi onları kabul etse bile. Yorumlayıcıyı yerinde tutmak, paket sürümlerini de yerinde tutmaktır.

Kilit Bir Yorumlayıcı İçin Üretilir

Orta tablo dokuz kurulum veriyor: üç kilit, üç hedef yorumlayıcı. 6 kabul, 3 ret.

Her satırın kendi deseni var. Y1 üzerinde üretilen kilit Y1 ve Y2’de kuruluyor, Y3’te reddediliyorolcum 1.1 ile rapor 1.0 o yorumlayıcıda kurulamıyor. Y2 ve Y3 üzerinde üretilen kilitler aynı kümeyi yazıyor ve ikisi de Y1’de reddediliyor.

Reddin ne olduğunu doğru okumak gerekir. Bu bir yükseltme hatası değildir; kilidin doğru davranışıdır. Kilit tam sürümler yazar ve pazarlık yapmaz; yazdığı sürüm hedef ortamda kurulamıyorsa yapabileceği tek şey durmaktır. Alternatifi, kilidi sessizce esnetip başka bir sürüm kurmak olurdu — ve o durumda kilit, kilit olmaktan çıkardı.

Kabul edilen altı kurulum 2 ayrı sürüm kümesi veriyor. Bu sayı üstteki tablonunkiyle aynı, ve tesadüf değil: kilitler de o çözümlemelerden üretildi. Kilit yeni bir küme yaratmaz, var olan bir kümeyi taşır.

Kilidin Güvence Verdiği Eksen

Alt iki satır dersin sonucudur ve kilidin ne tür bir güvence olduğunu tam olarak yazar.

Aynı kilit, sabit bir yorumlayıcıda üç kez kurulduğunda 1 ayrı sonuç, 0 ret veriyor. Aynı kilit üç ayrı yorumlayıcıda kurulduğunda yine 1 ayrı sonuç ama 1 ret veriyor. Kilit hiçbir yerde ikinci bir küme üretmedi — sözünü tuttu. Tutamadığı şey başkaydı: sözünü her ortamda tutamadı.

Buradan kilidin sınırı çıkıyor: kilit yeniden üretilebilirliği bir yorumlayıcı içinde sağlar; yorumlayıcı ekseninde sağlamaz. O eksende kilit bir güvence değil, bir kısıttır — ve kısıt olması kusur değil, işlevidir. Bir kilidin taşınamaması, taşınmaması gerektiğinin bildirimidir.

Pratik karşılığı doğrudan bir kuraldır: kilit dosyası, üretildiği yorumlayıcı sürümünü de yazmalıdır. Yazmadığında elde iki belge kalır — biri hangi sürümlerin kurulacağını söyler, öbürü hangi ortamda geçerli olduğunu söylemez — ve ret, ancak kurulum anında görünür. Bildirimin yorumlayıcı için de bir aralık taşıması aynı gerekçeyledir: proje hangi yorumlayıcılarda çalıştığını söylemezse, uyum tablosu ancak kurulum denenerek keşfedilir.

Bir üçüncü sonuç da sayıların dışında durur. Yorumlayıcı geçişi bir bakım işi gibi görünür, ama ölçüm onun bir çözümleme işi olduğunu gösteriyor: geçişte kilit yeniden üretilir, yeni küme eskisinden ayrı çıkabilir ve proje o yeni kümede sınanmamıştır. Geçişin maliyeti yorumlayıcıyı kurmak değil, yeni kümeyi doğrulamaktır.

Yan Yana Duran Yorumlayıcılar

Ölçümün üç satırı bir makinede üç yorumlayıcının aynı anda bulunabileceğini varsayar, ve bu varsayım gerçeğe uyar. Birden çok yorumlayıcı sürümünü yan yana tutan araçlar bir sınıf oluşturur — sürüm yöneticisi — ve yaptıkları iş bir seçimdir: hangi dizinde hangi yorumlayıcının çağrılacağı. Ürün adları burada da yazılmaz.

Seçimin nerede yapıldığı önemlidir. Sanal ortam kurulduğu anda bir yorumlayıcıya bağlanır; o noktadan sonra projenin hangi yorumlayıcıyı kullandığı bir yapılandırma ayarı değil, ortamın kimliğidir. Sürüm yöneticisinin seçtiği şey, yeni bir ortam kurulurken hangi yorumlayıcının kullanılacağıdır — var olan bir ortamı başka bir yorumlayıcıya devretmez.

Geçişin akışı bu yüzden beş adımdır ve hiçbiri atlanamaz: yeni yorumlayıcı kurulur, onun üzerinde yeni bir ortam kurulur, bildirim yeniden çözümlenir, yeni kilit üretilir, proje yeni kümede sınanır. Eski ortam ancak bundan sonra atılır. Ölçümün orta tablosu üçüncü ve dördüncü adımın neden atlanamayacağını gösteriyor: yeni yorumlayıcıda eski kilidi kurmayı denemek, üç durumdan birinde ret üretiyor.

Bir projenin aynı anda birden çok yorumlayıcıyı desteklemesi de aynı tablodan okunur. Ölçümde her yorumlayıcının kendi kilidi var: üç kilit, 2 ayrı küme. İki yorumlayıcıyı birden desteklemek, tek bir kilidi ikisine birden uydurmak değil, iki kilit tutmak demektir. Tek kilitle desteklenebilen yorumlayıcılar yalnız o kilitteki bütün sürümlerin ortak uyum kümesidir — tabloda Y2 ile Y3 böyle bir çifttir, Y1 ile Y3 değildir.

Yan yana durmanın bedeli de aynı tabloda duruyor: desteklenen her yorumlayıcı için ayrı bir site, ayrı bir kurulum ve ayrı bir kilit. Üçü de projenin verdiği her söz için ayrı ayrı ödenir; desteklenen sürüm sayısı arttıkça sabitlenmesi gereken küme sayısı da artar, ve her küme kendi başına doğrulanmayı bekler.

Özet

  • Yorumlayıcı da bir bağımlılıktır ve aday havuzunu daraltır; bildirim, depo ve strateji değişmeden 2 ayrı sürüm kümesi doğar.
  • Ayrı sonuç sayısı ortam sayısına değil uyum tablosuna bağlıdır: üç yorumlayıcı iki küme verir, çünkü ikisi aynı adaylara izin verir.
  • Bir yorumlayıcıda üretilen kilit başka birinde reddedilebilir: dokuz kurulumun 6’sı kabul, 3’ü rettir. Ret bir hata değil, kilidin doğru davranışıdır.
  • Kilit yeniden üretilebilirliği bir yorumlayıcı içinde sağlar, yorumlayıcı ekseninde sağlamaz; o eksende bir güvence değil bir kısıttır.
  • İki yorumlayıcıyı birden desteklemek tek kilidi ikisine uydurmak değil, iki kilit tutmaktır; tek kilit ancak sürümlerinin ortak uyum kümesindeki yorumlayıcıları kapsar.
  • Yorumlayıcı geçişi ortamın yeniden kurulmasıdır ve kilit yeniden üretilir; maliyeti kurulum değil, yeni kümenin doğrulanmasıdır.

Sonraki Adım

Bu konu boyunca dört eksen ölçüldü — yalıtım sınırı, çözümleme stratejisi, çözümleyicinin kendisi ve yorumlayıcı sürümü — ve dördü de aynı yöntemle tekleştirildi: kararı bir kez verdir, yazıya geçir, sonraki koşumlara okut. Kurulumun kaç ayrı sonuç verdiği artık sayılabiliyor.

Geriye kurulumun içindeki asıl şey kalıyor: kod. Ortam tek bir kümeye indirildiğinde, o kümede koşan kodun kendisi her koşumda aynı kararı veriyor mu? Sonraki konu bu soruyu sorar ve yanıtı ölçmek için testin ne olduğunu, bir takımın ne bildirdiğini ve aynı takımın kaç ayrı karar verebildiğini ele alır.

İ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