Kimseyi Beklettirmeden Daha Büyük Çalışma Alanlarına Geçiş
Her Mythex projesi kendi çalışma alanını alır: ajanın kod yazdığı ve uygulamanızın önizlemesinin çalıştığı küçük bir bulut bilgisayarı. Yeni çalışma alanlarının belleğini 1 GB'dan 2 GB'a çıkarmıştık, ama eskiler 1 GB'da kalmıştı; kontrol ettiğimiz gün bunların yaklaşık dörtte biri. İlk düzeltmemiz, bir projeyi bir sonraki açılışında daha büyük bir çalışma alanına taşıyordu. Üretimdeki ilk gününde bu, bir kişiyi yedi dakika bekletti. Bunun üzerine kesin bir zaman sınırı koyduk, sonra da taşımayı proje açmanın kendisinden tamamen çıkardık.
Eski çalışma alanları neden küçük kaldı
Sandbox sağlayıcımız bir çalışma alanının boyutunu oluşturulduğu anda belirler ve her duraklatma ve devam ettirmede bunu korur. Şablonu değiştirmek, yani yeni çalışma alanlarının üzerine kurulduğu tarifi değiştirmek, yalnızca değişiklikten sonra oluşturulan çalışma alanlarını etkiler. Mevcut olanları yeniden boyutlandıran hiçbir şey yoktu.
Bu önemliydi. Küçük çalışma alanlarından biri, önizlemesi başlarken bir git push sırasında bellek tükendi ve 11 dakika boyunca yanıt vermedi. Bir yayın da bu yüzden başarısız oldu.
İlk deneme: uyandığında projeyi taşı
Çalışma alanları kimse kullanmadığında duraklar ve proje açıldığında uyanır. Uyandığı an, projeyi taşımak için doğru an gibi görünüyordu, çünkü henüz kimse orada çalışmıyor.
Taşıma şöyle işliyordu:
- Boyutu kontrol et. Çalışma alanı 2 GB'dan küçükse taşı. Boyutu bilinmiyorsa hiçbir şey yapma.
- Bir yayını bozma. Yayın çalaşmanın dosyalarını okur; bu yüzden biri çalışıyorsa taşımayı atla.
- Projeyi paketle. Projedeki her şeyi arşivle; Git geçmişi dahil, yani projenin sahip olduğu her kontrol noktası, ve sahibine ait uygulamanın
.envdosyası dahil. Ama kurulu bağımlılıkları (node_modules) dışarıda bırak; bunlar yeniden kurulabilir. - Doğrudan aktar. Arşivi eski çalışma alanından yeni bir 2 GB'lık çalışma alanına akıt; böylece hiçbir zaman kendi sunucumuzun belleğine sığmak zorunda kalmaz.
- Geçmeden önce karşılaştır. Her iki çalışma alanında da dosyaları say, en son kontrol noktasını oku ve kontrol noktalarını say. Üçü de eşleşirse geç.
- Herhangi bir başarısızlıkta eskisini tut. Herhangi bir hata ya da uyuşmazlık yeni çalışma alanını atar ve proje eskisinde, her zamanki gibi açılır.
Karşılaştırmadaki bir ayrıntı göründüğünden daha önemliydi. Kontrol yönetici hesabıyla çalışıyor ve Git, başka bir kullanıcının sahip olduğu bir depoyu okumayı reddediyor. Her iki tarafta da hiçbir şey yazdırmadı; "hiçbir şey" ise "hiçbir şey"e eşit çıktı; böylece kontrol hiçbir geçmişi karşılaştırmadan geçti. Git'e dizine güvenmesini söyledik ve bunun geri dönmemesi için bir test ekledik.
İlk gün ne ters gitti
Üretimdeki ilk gününde, bir projeyi paketlerken uyanma sırasında beş dakikalık bir komut zaman aşımına uğradı. Sahibi çalışma alanının açılmasını yedi dakika bekledi. Taşıma başarısız olduğu için proje hâlâ küçüktü; bu yüzden bir sonraki açılış denemeyi tekrarlayacak ve onları yeniden bekletecekti.
Kişinin kendi projesini açarken beklemesini sağlayan bir geçiş, kötü bir takas. Uyandırırken yapmanın tüm amacı kimsenin fark etmemesiydi.
İkinci deneme: sabit bir bütçe
Aynı gün dört şeyi değiştirdik:
- Tüm taşıma için bir dakika. Her adım (boyutu kontrol etme, paketleme, yeni çalışma alanı oluşturma, kopyalama, açma, karşılaştırma) tek bir 60 saniyelik bütçeyi paylaşır. Bu bitince proje eski çalışma alanında açılır.
- Yalnızca beklemeyi değil, işi de durdur. Bizim tarafımızda vazgeçmek yetmez; sahibinin kullanmak üzere olduğu çalışma alanında arşivleme hâlâ çalışıyorsa, sorun orada devam eder. Her arşiv komutu artık bütçe bitmeden kısa bir süre önce, çalışma alanının içinde öldürülüyor. Biz vazgeçtikten sonra yeni çalışma alanı gelirse, o da atılır.
- Sahibi temizlik için bekletme. Geçici arşivin silinmesi artık arka planda oluyor.
- Her açılışta yeniden deneme. Taşınamayan bir proje 24 saat olduğu gibi bırakılır; böylece bir başarısızlık, her açılış yerine günde en fazla bir gecikmeye mal olur.
Üçüncü deneme: uyandırmanın dışına çıkar
Bu, en kötü durumu bir dakikaya indirdi. Ama bir dakika yine bir dakikadır ve taşımanın kimsenin yolunda olmasına gerek olmadığını fark ettik.
Artık 1 GB'lık bir çalışma alanı oluşturulmuyor. Yani bu süregelen bir süreç değil; sabit bir çalışma alanı listesiyle tek seferlik bir iş. Bunu uyandırmanın içinde yapmak, her yavaş taşımanın bedelini gerçek bir kişinin ödemesi anlamına geliyordu; bir çalışma alanının taşınamadığını öğrenmenin tek yolu da birinin tam o sırada beklemiş olmasıydı.
Bu yüzden taşımayı uyandırmanın tamamından çıkardık. Bir projeyi açmak eskisi gibi çalışır. Kalan küçük çalışma alanları, denetlenen bir toplu iş olarak ele alınıyor: kimse beklemiyor ve taşınamayan bir çalışma alanı, toplu işin raporunda görünüyor; orada inceleyebiliyoruz; sahibinin önünde değil.
Öğrendiklerimiz
- Yeniden boyutlandırma her zaman mümkün değildir. Bir platform boyutu oluşturulurken sabitlediğinde, varsayılanı yükseltmek yalnızca yeni şeylere yarar. Eskilerini planlayın.
- "Henüz kimse kullanmıyor" hâlâ birinin beklediği anlamına gelir. Bir ürüne girerken yapılan iş, bir kişinin izlediği iştir.
- Kullanıcının yolundaki her şeye bir bütçe koyun ve bütçe bittiğinde işi durdurun. Kendi tarafınızda zaman aşımına uğrayıp komutun başka bir yerde çalışmaya devam etmesine izin vermek, sorunu yalnızca başka bir yere taşır.
- Tek seferlik bir geçiş tek seferlik bir işe aittir. Onu sıradan eylemlerin içine gizlemek, yazmayı ucuzlatır, çalıştırmayı pahalılaştırır.
- Güvenlik kontrollerinizi test edin. Hiçbir şeyi karşılaştırmayan bir karşılaştırma, geçmiş bir karşılaştırmayla birebir aynı görünür.
Mythex'te yapabileceğiniz bir şey yok: amaç yalnızca bellekleri tükenen çalışma alanlarının sayısını azaltmak, bir projeyi açmayı da eskisi kadar hızlı tutmak. Çalışma alanlarının nasıl duraklayıp uyandığı, dokümantasyonda özel çalışma alanı başlığı altında anlatılıyor. Bellek tükenmesiyle ilgili başka bir hikâye için, bir ilerleme etiketinin içinde saklanan bellek sızıntısı yazısına bakın.