1. Form: Hata Onarıcı. 2. Form: Boşa Harcanan Rapor.
Dikkatla Ölçülen Kalp, ihtiyaç, değişiklik veya zamanlayıcının tetiklenmesi üzerine çalışır.
İki form, doğru tasarım yerine planlı bir işin yer aldığı ortak bir neden taşır.
1. Form: Hata Onarıcı
Bir durum geçişinin tam olarak atomik olarak tamamlanamaması. Yerine, arka planda gecikmeyle çalışan bir iş yürütülür ve uzlaştırılır. Kullanıcılar, uzlaştırma penceresi sırasında bozulmuş duruma maruz kalır.
GitHub örneği (2026-04-08): Bir pull request'ın upstream deposu özel hale getirildi. GitHub, durum geçişini denedi: PR'ı kapat, brancı durumu güncelle, birleştirmesi durumu sıfırla. Geçiş tam olarak atomik olarak tamamlanmadı. PR durumu 'branch-forced-closed' ve 'Birleşim durumu yüklenemiyor' olarak aynı anda görüldü. Birkaç dakika sonra Sidekiq arka plan işini tamamlandı ve uzlaştırma tamamlandı. Görevi görenler, işin yürütülmesi süresince bozulmuş duruma maruz kaldı.
Dikkatla Ölçülen Kalp: Sidekiq işinin çalıştırılması, GitHub'un bozulmuş duruma dikkat etmesi nedeniyle değil, zamanlayıcının tetiklenmesi nedeniyleydi. Gerçek zamanlı olarak PR'yi izleyen bir kullanıcı, işin yürütülmesi beklenirken PR'nın kendi kendine çelişkili hale geldiğini gördü.
2. Form: Boşa Harcanan Rapor
Bir rapor veya birleşim, sabit bir aralıklarla yeniden hesaplanır. Hiçbir önbellek denetimi. Hiçbir tekrarlanabilirlik koruması. Hiçbir artımlı güncelleme. Her yürütme: tam bir tarama.
Örnekler: her gece çalışan bir cron işini, her kullanıcının toplam satın alma miktarını, geçmiş zamanlardan başlayarak tüm siparişleri tarama. Gündelik analiz işini, doğrudan olay günlüklerinden bir pano yeniden oluşturma. Haftalık etkinlik tablosunu sorgulayan bir e-posta gönderme işini.
Her biri, önceki yürütme since son değişiklikten yeni veri içerdiyse bile, değişiklik yapılmadığı takdirde çalışır. Her biri, sadece son 24 saat yeni veri içerdiğinde bile, tam geçmişten tarama yapar. Her biri, artımlı tasarım yerine planlı tekrarlamayı kullanır.
Ortak Kök
Dikkatla Ölçülen Kalp, kendi durumunu doğru bir şekilde söyleyemez. Sadece zamanlayıcının tetiklenmesiyle bilgilendirilebilir. 1. Form: Hata onarıcı iş, T+5 dakikada çalışır ve durumun T+0'da bozulmuş olup olmadığına bakmaksızın. 2. Form: Rapor iş, önceki gün herhangi veri değişti mi bakmaksızın, her gece 2 AM'de çalışır.
Zamanlayıcının, yapılması gerekenler hakkında bilgi taşıma yeteneği yoktur. Bir olay, 'son durum geçişinin başarısız olduğu', 'yeni siparişler geldi' gibi bilgileri taşır. Dikkatla Ölçülen Kalp, bu bilgileri atar ve yerine bir zamanlayıcıyla değiştirir.
Kapital Söktürme
Yaşayan bir Kapital Söktürme: mühendisler kırık durum olayları için çağrıda beklemektedir. Sosyal güvende olanı eritir: kullanıcılar tutarlı olmayan verilere rastlar ve kendiliğinden çözünen kusurları bildirir. Diğer MOAD'ları (kötü tasarım örneği) güçlendirir: bir state-onarıcı iş, genellikle MOAD-0001 (O(N²) tarama) içerir. Bir rapor işi, soğuk yeniden hesaplayabilir ve MOAD-0005 (cache çölü) tetikleyebilir. MOAD-0009 diğer kusurları katlar.
Paylaşılan Kök
Form 1 & Form 2 görünüşte farklı görünür: biri durumu düzeltir, diğeri verileri yeniden hesaplar. Nedeni onları birleştirir.
Değişiklik Zamanında Ateşle, Saat Zamanında Olmaz
Olaya dayalı tasarım, bir şey değiştiğinde ateşler. Durum değişikliği olayıdır. Olay, tetikleyici.
Form 1: atomik geçiş, onarıcı işi değiştirir.
Eğer bir durum geçişi, sistemi kırık bir ara duruma bırakabilirse, kusur geçişte, eksikliği değil onarıcı işte bulunur. Geçişi tam olarak atomik (veya transaksyonel) hale getirin. Geçiş tam olarak atomik olduğunda, kırık durum asla mevcut değildir. Onarıcı işi, düzeltme yapması gereken hiçbir şey yoktur.
# KUSUR: atomik olmayan geçiş kırık durumu bırakır
def close_pr_on_repo_private(pr_id):
pr = PR.get(pr_id)
pr.status = 'branch-forced-closed' # adım 1: kısmi durum
pr.save() # kullanıcılar tarafından şimdi görünür
# ... diğer adımlar başarısız olabilir ...
pr.merge_status = 'not_applicable'
pr.save() # adım 2: şimdi tutarlı
# Sideki job, adım 2 başarısız olursa uyumlu kılar
# FIX: atomik geçiş; hiçbir ara durum görünür olmayacak
def close_pr_on_repo_private(pr_id):
with db.transaction():
pr = PR.get(pr_id)
pr.status = 'branch-forced-closed'
pr.merge_status = 'not_applicable'
pr.save() # her iki alan atomik olarak kaydedilir; yarı yazılmış asla
Form 2: Artımlı güncelleme, tam yeniden hesaplamayı değiştirir.
Eski verilerle yeni veriler eklenince sonuç yeniden hesaplanır. Ama eski sonuç + delta, aynı yeni sonuç, artımlı olarak hesaplanır. Olay: yeni veriler geldi. Tetikleyici: güncellemeyi yeni verilere göre yap.
# EKSİK: tam yeniden hesaplama zamanlamasıyla
def nightly_totals_job():
for user in all_users():
total = sum(o.amount for o in user.orders) # tüm zamanların taraması
user.total_purchases = total
user.save()
# FIX: olaya dayalı artımlı güncelleme
def on_order_placed(order):
order.user.total_purchases += order.amount # delta sadece
order.user.save()
Artımlı güncelleme, bir sipariş geldiğinde değil, 2 AM'de tetiklenir. Sadece etkilenecek kullanıcının güncellenir. Sadece yeni sipariş okunur, tüm zamanlardan tüm siparişler okunmaz. Gece işi ortadan kalkar.
Neden Form 1, Bir Geçişin Bıraktığı Yetersiz Bir Durum Gösterir
Form 1 Ölçülmüş Kalp, bir durum geçişinin tamamlanmamış olduğunu gösterir. Onarıcı iş, bir mühendis, bozulmuş durumu fark etti ve bir uzlaştırma mekanizması eklemek yerine geçişi düzeltmek yerine ekledi. Onarıcı iş: Bozuk bir mimari kararı üzerinde bir yamadır.
MOAD-0009'u Güçlendirme
MOAD-0009, diğer MOAD'ları güçlendirir. Bir durumu onarmak için tüm kayıtları tarama işlevi: MOAD-0001 (O(N) veya O(N²) tarama her iş çalıştırıldığında). Bir şeyin her zaman sıcak bir üst kaynağı vurduğu zaman iş başlangıcında ve sıcak bir üst kaynağı vurduğu zaman iş başlangıcında soğuk yeniden hesaplayan bir rapor işi: MOAD-0005 (cache stampede). MOAD-0009, sadece kendi zararını değil; diğer MOAD'ları düzenli aralıklarla teslim eder.
Tanı ve Yeniden Tasarım
Gece zamanı bir cron işleği 2 AM'de çalışır. İş, tüm kullanıcıların tüm siparişlerini tarar ve her kullanıcının toplam alışveriş miktarını sıfırdan yeniden hesaplar. İş 4 saat sürer. 6 AM'de, ana panel yeni toplamaları gösterir. 2 AM & 6 AM arasında, ana panel geçen günkü toplamaları gösterir.