· kaynak Hacker News – Front Page (native)
celld'nin deterministik simülasyon testi, self-hosted Workers runtime'ında alarm yarış durumunu yakaladı
Self-hosted Cloudflare Workers runtime'ı celld, deterministik simülasyon testinin yeniden başlatma sonrası onaylanmış bir zamanlanmış görevin sessizce atlanmasına yol açabilecek bir alarm yarış durumunu nasıl bulduğunu ve düzelttiğini anlatıyor.

Cloudflare Workers ve Durable Objects uygulamalarını kendi makinelerinizde çalıştırmak için kullanılan runtime celld, eşzamanlılık hatalarını avlamak için deterministik simülasyon testini nasıl kullandığını anlatan bir mühendislik yazısı yayımladı. Bu yaklaşım şimdiden karşılığını verdi: Yazıya göre ekibin simülatörü, bir düğümün yeniden başlatılmasından sonra onaylanmış bir alarmın atlanmasına yol açabilecek, daha önce bilinmeyen bir alarm zamanlama yarış durumunu ortaya çıkardı.
Hacker News'te öne çıkan yazıda celld, kasıtlı olarak küçük bir ayak izine sahip dağıtık bir sistem olarak tanımlanıyor — tek dış servis bağımlılığı S3 uyumlu bir nesne deposu. Dağıtıklık aynı zamanda hataların peşinden gitmeyi zorlaştıran şey: Bir hata, gecikmeli mesajların, başarısız yazma işlemlerinin ve yeniden başlatmaların belirli bir kesişimine bağlı olabilir ve bu kesişim bir sonraki test çalıştırmasında tekrarlanmaz; bu da hem teşhisi hem de düzeltmenin doğrulanmasını güçleştirir.
Simülatör nasıl çalışıyor
celld'ye göre simülatör, runtime'ın üretim kodunu kontrollü bir ortam içinde çalıştırıyor. Cell — uygulama kodunu çalıştıran ve bir SQLite veritabanına sahip olan birim — gelen istekler, tamamlanan depolama işlemleri ve zamanlayıcı tetiklenmeleri gibi olaylara tepki veriyor. Hangi olayın sonra gerçekleşeceğine karar veren kod, o olayı işleyen koddan ayrı tutuluyor; böylece simülatör sıralamayı dikt ederken işleme mantığı üretimde çalışanla birebir aynı kalıyor.
Simülatör ayrıca asenkron görevlerin ne zaman çalıştırılacağını ve nesne deposunun nasıl yanıt vereceğini de kontrol ediyor; yazmaları geciktirme veya başarısız kılma dahil — ve gerçek zamanın geçmesini beklemeden simüle edilmiş zamanı ileriletebiliyor. Testler izin verilen istek ve hata alanını tanımlıyor; bu sınırlar içinde simülatör rastgele seçim yapıyor. Rastgele sayı üretecini bir seed başlatıyor; böylece aynı kod, ayarlar ve seed her zaman aynı olay dizisini ve aynı sonucu üretiyor. Her adımdan sonra bir denetleyici, değişmezleri doğruluyor — sistemin bir çalışma boyunca korumak zorunda olduğu koşulları, örneğin onaylanmış bir alarmın her zaman cell'ini uyandırmanın bir yolunu elinde bulundurmasını.
Ortaya çıkardığı alarm yarış durumu
celld'de alarmlar bir cell'i belirli bir zamanda uygulama kodunu çalıştırmak üzere zamanlar ve boşta olan cell'ler bellekten kaldırılıp gerektiğinde yeniden yüklenebilir. Bekleyen alarmları aramak için her cell'in SQLite veritabanını açmak pahalı olacağından, celld nesne deposunda hangi cell'in ne zaman yeniden etkinleştirileceğini kaydeden uyandırma girdileri tutuyor.
O dönemde celld, depolama yazmalarını azaltmak için uyandırma girdilerini yeniden kullanıyordu: Bir uygulama 10:00'deki alarmı silip 10:05 için yeni bir alarm belirlese, geriye kalan 10:00 girdisi cell'i yine de yeterince erken uyandırırdı. Eski alarmın silinmesi ayrıca, istemciye başarı zaten döndürüldükten sonra bayat uyandırma girdisini kaldıran bir arka plan temizlik görevi başlatıyordu; böylece istemci ek depolama işlemini beklemezdi.
Simülatör, istemcinin 10:05 alarmını belirlediği, onayı aldığı ve ancak bundan sonra gecikmiş temizliğin çalışarak yeni alarmın bağlı olduğu tek uyandırma girdisini sildiği bir sıralama buldu. Denetleyici ihlal edilen değişmezi işaretledi: alarm SQLite'ta vardı ama cell'i yeniden etkinletecek hiçbir şey kalmamıştı. Düğüm 10:05'ten önce yeniden başlatılsaydı, daha önceki başarı yanıtına rağmen alarm hiç tetiklenmeyebilirdi. Özellikle belirtmek gerekir ki celld, hiçbir elle yazılmış testin bu diziyi öngörmediğini söylüyor; simülatör bunu keşif yoluyla buldu.
Yeniden üretme ve düzeltme
Aynı seed hatayı tam olarak yeniden ürettiği için mühendisler, sıralamayı yeniden aramak zorunda kalmadan her çalıştırmada temizliğin gereken girdiyi sildiği kesin anı inceleyebildi. Ekip o zamandan beri uyandırma girdilerini yeniden tasarladı: Artık her alarm belirlemesi nesne deposuna kendi girdisini yazıyor. Eski bir alarmın gecikmiş silme işlemi artık yalnızca o eski girdiyi kaldırabiliyor ve yeni girdiyi olduğu gibi bırakıyor; bayat girdiler ise celld artık gerekli olmadıklarını onayladığında kaldırılıyor. Simülatörün kendisi geliştirilmeye devam ediyor ve celld'nin herkese açık deposunun bir parçası değil.
Neden önemli
Yeniden üretilebilirlik, dağıtık sistemler hata ayıklamasında en kıt kaynak ve seed'li simülasyon, nadir ve nondeterministik hataları deterministik, yeniden oynatılabilir izlere dönüştürüyor. celld yazısı bu getirinin kompakt bir kanıtı: asenkron temizlik bitmeden başarı döndürmek ile yeniden kullanılabilir bir kaynağın birleşiminden oluşan ve geleneksel örnek temelli testlerin kolayca gözden kaçırdığı bir hata sınıfı. Workers ve Durable Objects iş yükleri Cloudflare'in yönetilen edge'i dışındaki self-hosted runtime'lara taşındıkça, yeniden başlatmalardan sonra alarmların tetiklenmesi gibi doğruluk garantileri runtime operatörünün sorumluluğu haline geliyor. Benzer altyapılar inşa eden ekipler için bu yazısı aynı zamanda pratik bir şablon: zamanlamayı işlemeden ayırın, hataları ve zaman kontrolünü sınırlarda enjekte edin ve bir denetleyicinin her adımdan sonra değişmezleri doğrulamasına izin verin.
- #cloudflare-workers
- #distributed-systems
- #testing
- #durable-objects
- #cloud