İçeriğe geç
academia.sh

Ders 11 / 15

İş Takibi ve Panolar

İş öğesinin durumları arasında geçen bekleme incelemenin dışında 19 birimdir; inceleme atamaya göre 12 ile 36 arasında değişir ve zincirin payının 0,387'sinden 0,655'ine çıkar, kalan üç kusur öğeyi panoya geri koyunca toplam 31'den 105'e gider.

İçindekiler

Buraya kadar inceleme tek bir değişikliğin çevresinde ölçüldü: kaç eksene bakıldı, kaç öbek okundu, kaç tur döndü. Değişiklik bu ölçümlerde tek başına duruyordu — bir yerden gelmiyor, bir yere gitmiyordu. Oysa bir ekipte değişiklik yalnız bir değişiklik değildir; bir akışın içindeki bir öğedir. Önce bir öneri olarak doğar, bir sıraya girer, biri onu üstlenir, yazılır, incelenir, tümleşir ve kapanır.

Bu zincirde inceleme yalnız bir halkadır. Bu dersin sorusu şudur: halkanın kendisi ne kadar sürüyor, ve zincirin tamamında payı ne? İnceleme turunu kısaltmanın değerini bilmek için önce turun neyin içinde durduğunu bilmek gerekir. Zincirin geri kalanı incelemeden uzunsa, inceleme turunu yarıya indirmek toplamda az şey değiştirir.

İş Öğesi ve Durumları

İş öğesi (work item), bir ekibin izlediği en küçük iş birimidir: bir hata kaydı, bir istek, bir görev. Öğenin tek bir kimliği, tek bir sahibi ve her an tek bir durumu vardır. Pano (board), bu öğelerin durumlarına göre dizildiği yüzeydir; her sütun bir durumdur ve öğe soldan sağa ilerler.

Pano bir kayıt aracı değil, bir görünürlük aracıdır. Aynı bilgi bir listede de durabilir; panonun eklediği şey, hangi durumda kaç öğe biriktiğinin bakışta okunmasıdır. Bir sütunun şişmesi, o durumdan çıkışın girişten yavaş olduğunu söyler.

# örnek pano dökümü — çalıştırılmamıştır

öneri        sırada        yazılıyor     incelemede    tümleşti
─────────    ──────────    ──────────    ──────────    ──────────
#412         #398          #377          #361          #350
#411         #395          #374          #359
             #391                        #356
             #388                        #352
                                         #349

Durum kümesinin kendisi bir tasarım kararıdır ve tek ölçütü vardır: bir durum, çıkışı başkasının eylemine bağlı olduğunda anlamlıdır. incelemede bir durumdur çünkü öğe orada yazanın değil inceleyenin eylemini bekler. Çıkışı hep aynı kişinin elinde olan bir sütun ise durum değil, o kişinin özel listesidir; panoda yer kaplar ve hiçbir bekleme bildirmez. Aynı ölçüt sütun sayısını da sınırlar: her yeni durum ancak yeni bir devir noktası varsa eklenir.

Bu dökümde incelemede sütunu beş öğe taşıyor, yazılıyor iki. Sayının kendisi bir kusur değildir; kusur, sütunun boşalma hızının dolma hızından düşük olmasıdır. Beş öğe orada biriktiyse inceleme kuyruğu (review queue) uzuyor demektir ve kuyruğun uzaması öğelerin her birine bekleme yazar.

Bekleme Durumda Değil Geçişte Durur

Panonun kolay yanılttığı nokta budur. Bir öğe incelemede sütununda dururken geçen zamanın tamamı inceleme değildir; bir bölümü inceleyenin öğeye bakmasını beklemektir. Ölçülecek şey öğenin bir sütunda durduğu süre değil, bir sütundan diğerine geçmesi için geçen süredir.

Bu ayrım ölçümü tanımlar. Zincirde beş geçiş vardır ve bunların dördü incelemenin dışındadır: öneri sıraya girer, sıradan biri onu üstlenir, yazım biter ve öğe incelemeye çıkar, inceleme biter ve öğe kapanır. Beşinci geçiş — incelemede durumundan tümleşti durumuna — incelemenin kendisidir ve sabit değildir: kaç tur döndüğüne bağlıdır.

Bekleme süresi (wait time) burada birimsiz sayılır. Saat ya da gün değil, karşılaştırılabilir bir birimdir; amaç mutlak süreyi değil, halkaların birbirine oranını okumaktır. Bu ölçütler sürecin ölçütleridir: bir öğenin ne kadar beklediği, o öğeye bakan kişinin değil, zincirin biçiminin sonucudur.

Sütun Uzunluğu ile Bekleme Aynı Şey Değildir

Panonun incelemede sütununda duran beş öğe bir birikimdir; geçişte ölçülen bekleme ise bir hızdır. İkisi aynı sayıyı vermez. Beş öğelik bir sütun, çıkış hızı birim başına beş öğeyse tek birimlik bekleme demektir; çıkış hızı birim başına bir öğeyse beş birimlik bekleme demektir. Sütuna bakan biri iki durumu ayırt edemez, çünkü pano birikimi gösterir ve hızı göstermez.

Bunun doğrudan sonucu şudur: sütunu kısaltmak beklemeyi kısaltmaz. Beş öğeden ikisini başka bir sütuna taşımak birikimi düşürür ve panoyu rahatlatır; geçişin ne kadar sürdüğüne dokunmaz. Beklemeyi kısaltan tek şey geçişin kendisini hızlandırmaktır ve inceleme halkasında bunun anlamı tur sayısını düşürmektir.

Bir ayrım daha gerekiyor. Bir iş öğesi birden çok değişiklik taşıyabilir; o zaman inceleme halkası öğe başına birden çok kez yürür ve zincirin toplamı buna göre büyür. Bu ölçüm öğe başına tek değişiklik sayar ve sayıları o varsayımla verir. Öğe üç değişikliğe bölünmüşse inceleme dışı geçişler bir kez, inceleme halkası üç kez ödenir — payı da o oranda büyür. Bu, öğeleri bölmenin bedava olmadığını söyler: bölme incelemeyi kolaylaştırır ama zincirdeki inceleme payını yükseltir.

İncelemenin Zincirdeki Yeri

İnceleme halkasının uzunluğunu ne belirler? Kursun beşinci okuması bunu söylüyordu: turu ve beklemeyi uzatan şey ilk turda görülemeyendir. Bir turda bulunanlar düzeltilir; bulunmayanlar sonraki tura kalır ve her tur zincire bir bekleme daha yazar. Eksen çeşitliliği düşükse ilk tur az bulur, tur sayısı artar, halka uzar.

Dolayısıyla zincirin toplamı iki kaynaktan beslenir. Biri sabit kısımdır — öneri, sıra, yazım ve kapanış geçişleri; bunlar incelemenin nasıl yapıldığından bağımsızdır. Diğeri değişken kısımdır ve doğrudan eksen atamasının sonucudur. Ölçüm bu ikisini ayrı sayar ve oranlarını verir.

Bir kusur daha vardır: turlar bittiğinde kalan kusur. Kalan kusur inceleme bitmiş, öğe kapanmış demek değildir; kapanan öğe daha sonra o kusur yüzünden yeniden açılır ve zincire ikinci kez girer. Bu ikinci geçiş öneriyle başlamaz — öğe zaten önerilmiştir — ama sıradan itibaren her şeyi tekrarlar.

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

  • EA1 — Ortak tanımın 600 satırlık değişikliği ve 24 kusuru olduğu gibi kullanılır; sınıf dağılımı ve kâhin kursun sabitidir.
  • EA2 — İnceleme dışı dört geçişin beklemesi sabittir ve atamadan bağımsızdır: sırasıyla 5, 9, 2 ve 3 birim. Bu değerler zincirin biçimini temsil eder, bir ekibin ölçümü değildir.
  • EA3 — İnceleme halkasının beklemesi ortak tanımın tur döngüsünden gelir: her tur 6 birim yazar ve tur sayısı ilk turda bulunan kusur sayısının sonucudur.
  • EA4 — Bulunan kusur o turda düzeltilmiş sayılır; kalan kusur sonraki tura taşınır. Altı tur üst sınırdır ve bu sınıra dayanan atamada kusur kalır.
  • EA5 — Kalan kusur öğeyi kapandıktan sonra bir kez yeniden açar. İkinci geçiş sırada durumundan başlar; öneri geçişi tekrarlanmaz.
  • EA6 — Ölçüt öğe başına raporlanır, kişi başına değil. Zincirdeki hiçbir sayı bir rolün başarımı olarak okunamaz; hepsi zincirin biçiminin sonucudur.
  • EA7 — Kümenin çözünürlüğü 24 kusurda 1/24’tür; bekleme birimi tur başına 6 olduğu için zincirde ölçülebilen en küçük fark 6 birimdir.

Ölçüm

"""Is ogesi zinciri: durumlar arasi bekleme ve incelemenin payi.

Bolum 1 - dort atamada bulunan, kacan ve inceleme beklemesi.
Bolum 2 - zincirin toplami, incelemenin payi ve yeniden acilma bedeli.
"""
TOHUM = 20260815
EKSENLER = ("arayuz", "gerceklestirim", "test", "belge", "bicim")
YAZILMAYAN = "eksik gereksinim"
SINIFLAR = EKSENLER + (YAZILMAYAN,)
DIKKAT, OBEK = 12, 50
# Incelemenin disinda kalan gecisler: pano uzerinde okunan bekleme.
DIS = (("öneri", "sırada", 5), ("sırada", "yazılıyor", 9),
       ("yazılıyor", "incelemede", 2), ("tümleşti", "kapandı", 3))


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def degisiklik(satir, kusur_sayisi=24, tohum=TOHUM):
    r, kusurlar = uretec(tohum), []
    obek_sayisi = max(1, satir // OBEK)
    for i in range(kusur_sayisi):
        kusurlar.append({"no": i + 1, "sinif": SINIFLAR[r(6)],
                         "obek": r(obek_sayisi)})
    return {"satir": satir, "obek": obek_sayisi, "kusurlar": kusurlar}


def incele(d, eksenler, dikkat=DIKKAT):
    okunan = set(range(min(dikkat, d["obek"])))
    return {k["no"] for k in d["kusurlar"]
            if k["sinif"] in eksenler and k["obek"] in okunan}


def kurul(d, atamalar, dikkat=DIKKAT):
    bulunan = set()
    for eksenler in atamalar:
        bulunan |= incele(d, eksenler, dikkat)
    return bulunan


def tur_dongusu(bulunan, kusur_sayisi, tur_basina_bekleme=6):
    kalan, tur, bekleme = kusur_sayisi - len(bulunan), 1, tur_basina_bekleme
    while kalan > 0 and tur < 6:
        tur += 1
        bekleme += tur_basina_bekleme
        kalan -= max(1, len(bulunan) // 2)
    return tur, bekleme, max(0, kalan)


TAM = set(EKSENLER)
ATAMALAR = {
    "tek inceleyici, tüm eksenler": [TAM],
    "üç inceleyici, aynı eksen": [{"gerceklestirim"}] * 3,
    "üç inceleyici, ayrı eksen": [{"arayuz"}, {"gerceklestirim"}, {"test", "belge"}],
    "beş inceleyici, beş eksen": [{e} for e in EKSENLER],
}
DIS_TOPLAM = sum(b for _, _, b in DIS)
d = degisiklik(600)

print(f"iş öğesi 1 | değişiklik {d['satir']} satır, {d['obek']} öbek, "
      f"kusur {len(d['kusurlar'])} | inceleme dışı bekleme {DIS_TOPLAM}")
print("inceleme dışı geçişler: "
      + ", ".join(f"{a}→{b} {n}" for a, b, n in DIS))
print()
print(f"{'atama':<30s} {'bulunan':>7s} {'kaçan':>5s} {'yazılmayan':>10s} "
      f"{'tur':>3s} {'inceleme':>8s} {'kalan':>5s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    kacan = [k for k in d["kusurlar"] if k["no"] not in b]
    yaz = sum(1 for k in kacan if k["sinif"] == YAZILMAYAN)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    print(f"{ad:<30s} {len(b):7d} {len(kacan):5d} {yaz:10d} "
          f"{tur:3d} {bekleme:8d} {kalan:5d}")

print()
print(f"{'atama':<30s} {'zincir':>6s} {'inceleme payı':>13s} "
      f"{'yeniden açılma':>14s} {'toplam':>6s}")
for ad, atama in ATAMALAR.items():
    b = kurul(d, atama)
    tur, bekleme, kalan = tur_dongusu(b, len(d["kusurlar"]))
    zincir = DIS_TOPLAM + bekleme
    # Kalan kusur öğeyi panoya geri koyar: sırada durumundan başlayan ikinci tur.
    yeniden = 0 if kalan == 0 else zincir - DIS[0][2]
    print(f"{ad:<30s} {zincir:6d} {bekleme / zincir:13.3f} "
          f"{yeniden:14d} {zincir + yeniden:6d}")
iş öğesi 1 | değişiklik 600 satır, 12 öbek, kusur 24 | inceleme dışı bekleme 19
inceleme dışı geçişler: öneri→sırada 5, sırada→yazılıyor 9, yazılıyor→incelemede 2, tümleşti→kapandı 3

atama                          bulunan kaçan yazılmayan tur inceleme kalan
tek inceleyici, tüm eksenler        22     2          2   2       12     0
üç inceleyici, aynı eksen            6    18          2   6       36     3
üç inceleyici, ayrı eksen           15     9          2   3       18     0
beş inceleyici, beş eksen           22     2          2   2       12     0

atama                          zincir inceleme payı yeniden açılma toplam
tek inceleyici, tüm eksenler       31         0.387              0     31
üç inceleyici, aynı eksen          55         0.655             50    105
üç inceleyici, ayrı eksen          37         0.486              0     37
beş inceleyici, beş eksen          31         0.387              0     31

Zincirin Okunması

İnceleme dışı bekleme 19 birimdir ve dört satırın dördünde de aynıdır. Değişen tek şey inceleme halkasıdır ve o 12 ile 36 arasında gidiyor. Zincirin toplamı böylece 31 ile 55 arasında oynuyor: en kötü atama, en iyisinden %77 daha uzun bir zincir üretiyor.

İncelemenin payı sağdaki sütunda. En iyi atamada zincirin 0,387’si inceleme; yani öğenin beklemesinin yaklaşık üçte ikisi incelemenin dışında geçiyor. En kötü atamada pay 0,655’e çıkıyor — inceleme artık zincirin yarısından fazlası. Bu iki sayının arasındaki fark bir sonuç veriyor: inceleme sabit maliyetli bir halka değil, zincirin en oynak halkasıdır.

Buradan pratik bir sıralama çıkar. sırada→yazılıyor geçişi 9 birimle inceleme dışı en uzun halkadır ve iyi atamada tek başına inceleme halkasının dörtte üçü kadardır. Zincirin en iyi durumunda kısaltılacak yer inceleme değil, sıradır. Ama kötü atamada inceleme 36 birimdir ve sıranın dört katıdır; orada sırayı kısaltmanın toplama katkısı küçük kalır. Hangi halkanın kısaltılacağı, atamanın hangisi olduğuna bağlıdır ve bunu panodaki sütun uzunluğu değil, geçiş beklemesi söyler.

Soldaki tablo aynı satırlarda bulunan ve kaçan sayısını da veriyor ve ikisi birlikte okunmalı. üç inceleyici, aynı eksen satırı 6 bulup 18 kaçırıyor; zincirin en uzun olduğu satır, aynı zamanda en az bulan satır. tek inceleyici, tüm eksenler 22 bulup 2 kaçırıyor ve zincirin en kısası. Yani uzun zincir daha iyi bir inceleme satın almıyor — uzunluğun kaynağı zaten bulunamayanlardır.

Kaçanların içinde her satırda 2 tane eksik gereksinim kusuru var ve bu sayı dört satırda da değişmiyor. Zincirin biçimi, atamanın çeşitliliği, tur sayısı — hiçbiri o iki kusuru bulmuyor. İş takibi bu sınıfın çaresi değildir; öğe panoda ne kadar iyi izlenirse izlensin, gönderilmemiş olanın yokluğu incelemeye görünmez.

Yeniden Açılma

İkinci tablonun son iki sütunu zincirin gerçek maliyetini veriyor. üç inceleyici, aynı eksen atamasında altı tur sonunda 3 kusur hâlâ duruyor. Öğe kapanmıştır; kusurlar kapanmamıştır. Kalan kusur eninde sonunda bir yerde ortaya çıkar ve öğe yeniden açılır.

Yeniden açılma zincire 50 birim ekliyor: öneri dışındaki her geçiş bir kez daha yürüyor. Toplam 55’ten 105’e çıkıyor. Aynı değişiklik, en iyi atamada 31 birimde kapanıyor; buradaki fark 74 birim, yani üç kat fazlası.

Bu sayının okunma biçimi önemlidir. Yeniden açılma bir gecikme değil, ertelenmiş bir beklemedir: zincirin ilk geçişinde ödenmeyen bekleme, ikinci geçişte faiziyle ödenir. Panoya bakan biri ilk geçişte hiçbir sorun görmez — öğe kapanmıştır, sütun boşalmıştır, sayılar temizdir. Sorun panoda, öğe geri döndüğünde belirir ve o an artık ilk incelemenin ölçümüyle ilişkilendirilmez.

Bu yüzden bir panonun okunabilmesi için kapanan öğe sayısı tek başına yetmez. Yeniden açılan öğe sayısı ayrı bir sütun ya da ayrı bir sayım olarak durmalıdır; yoksa zincirin en pahalı davranışı hiçbir yerde görünmez. Kapanış sayısı, ilk geçişte kapanan ile ikinci geçişte kapananı ayırmadığı sürece iki farklı süreci aynı sayıyla raporlar.

Özet

  • İş öğesi bir akıştaki en küçük iş birimidir; pano öğeleri durumlarına göre dizer ve bekleme durumların içinde değil, durumlar arasındaki geçişlerde birikir.
  • Zincirin inceleme dışı beklemesi 19 birimle sabittir; inceleme halkası atamaya göre 12 ile 36 arasında değişir ve zincirin toplamını 31’den 55’e taşır.
  • İncelemenin zincirdeki payı 0,387 ile 0,655 arasındadır; inceleme sabit maliyetli bir halka değil, zincirin en oynak halkasıdır ve hangi halkanın kısaltılacağı atamaya bağlıdır.
  • Uzun zincir daha iyi bir inceleme satın almaz: 36 birimlik halka 6 kusur bulup 18 kaçırır, 12 birimlik halka 22 bulup 2 kaçırır.
  • Altı tur sonunda kalan 3 kusur öğeyi yeniden açar ve zincire 50 birim daha ekler; toplam 105’e çıkar. Kapanış sayısı bu ikinci geçişi ayrı saymadıkça gizler.
  • Dört atamanın dördünde de 2 eksik gereksinim kusuru kaçar; iş takibi bu sınıfı bulmaz.

Sonraki Adım

Bu ölçümde öğeyi yazanın ne göndereceğini bildiği varsayıldı: zincire giren değişiklik, ekibin beklentilerini karşılamaya çalışılarak yazılmış bir değişiklikti. Peki yazan o beklentileri nereden biliyor? Ekibin içindeki biri onları turlarda öğrenmiştir; dışarıdan gelen biri öğrenmemiştir. Yazılmamış bir beklenti, incelemenin ilk turunda bir bulgu olarak geri döner ve her bulgu bir tur daha yazar. Sonraki ders bu beklentilerin yazılı hâlini ölçer: katkı rehberi hangi sınıfları incelemeden önce kapatır, kapattığı her sınıf kaç tur eksiltir, ve hiçbir eksenin aramadığı sınıfa dokunabilen tek düzenek gerçekten rehber midir?

İ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