Yavaş dağıtımın yol açtığı toplantılar (2015)
(tidyfirst.substack.com)- Mühendislerin “toplantılar yüzünden kod yayınlayamıyoruz” diye hissettiği durumda, asıl neden yavaş dağıtım yeteneğinin yarattığı organizasyonel ek yük olabilir
- Facebook'tan Chuck Rossi, tek bir dağıtımın kaldırabileceği değişiklik sayısının neredeyse sabit göründüğünü ve değişiklik hacmini artırmak için dağıtım sayısını artırmak gerektiğini savunuyor
- Facebook, PHP kod dağıtımlarını haftalıktan günlüğe, ardından günde 3 sefere çıkardı; mobil uygulama dağıtım döngüsünü de 6 haftadan 4 haftaya, ardından 2 haftaya indirdi ve bunu büyük ölçüde release engineering ekibi yürüttü
- Üretilen değişiklik miktarı dağıtım sınırını aştığında, dağıtım başına değişiklik sayısı kolayca artmaz; bunun yerine toplantı, inceleme ve handoff gibi ek yükler artar ve organizasyon toplam değişiklik miktarını düşürecek şekilde uyum sağlar
- Daha fazla değişikliği sisteme geçirmek için sadece toplantıları azaltmak yetmez; dağıtım döngüsü, test, izleme, izolasyon ve ekip içi sosyal ilişkiler iyileştirilerek dağıtım kapasitesinin büyütülmesi gerekir
Toplantılar neden değil sonuç olabilir
- “Toplantı çok olduğu için kod dağıtamıyoruz” şeklindeki yaygın şikayette nedensellik tersine dönmüş olabilir
- Organizasyonel ek yük eklemek ya da kaldırmak görece kolaydır, ancak organizasyonun kod dağıtım kapasitesini artırmak daha zordur
- Toplantılar ve incelemeler, dağıtım sisteminin aşırı yüklenmemesi için organizasyonun geliştirdiği bir uyum mekanizmasının sonucu olabilir
- Chuck Rossi, Facebook'ta tek bir dağıtımın işleyebileceği değişiklik sayısının sanki sabitmiş gibi göründüğünü gözlemliyor
- Daha fazla değişiklik isteniyorsa daha fazla dağıtım gerekir
- PHP kod dağıtımları haftalıktan günlüğe, ardından günde 3 sefere çıktı
- Mobil uygulama dağıtım döngüsü 6 haftadan 4 haftaya, ardından 2 haftaya indi
- Bu iyileştirmeleri esas olarak release engineering ekibi sürükledi
Dağıtım kapasitesi artmazsa ek yük büyür
- “Dağıtım başına değişiklik sayısı”, kolay artmayan esnek olmayan bir metrik gibi görünür; iyileşmesi için büyük çaba gerekir
- Üretilen değişiklik sayısı mevcut sınırı aştığında, dağıtım başına değişiklik sayısını artırmaktan ziyade toplam değişiklik miktarını azaltmaya dönük bir baskı oluşur
- Toplantılar, incelemeler, handoff'lar ve diğer ek yükler artar
- Zamanla heyecan ve inisiyatif de azalabilir
- Ek yük artışı bir pozitif geri besleme döngüsü oluşturabilir
- Tamamlanan iş miktarı azalır
- Baskı artar
- Hatalar çoğalır
- Dağıtım başına değişiklik sayısı daha da düşer
- Ek yük yeniden artar
- Yalnızca ek yükü azaltmaya yönelik izole girişimler, baskıyı artırıp ek yükün yeniden büyümesine yol açabilir
- Daha fazla değişikliği geçirmek için “hortumun en uzak ucundaki” dağıtım kapasitesini genişletmek gerekir
- Zor yöntem: dağıtım döngüsünü kısaltmak ve bunun getirdiği karmaşayı yönetmek
- Daha da zor yöntem: daha iyi test, izleme, bileşenler arası izolasyon ve ekip içi sosyal ilişkiler sayesinde dağıtım başına değişiklik sayısını artırmak
- Sadece toplantıları azaltmaya odaklanan girişimler, “toplantıları nasıl azaltacağımızı konuştuğumuz bir toplantı”ya dönüşebilir
- Bu, ilk bakışta yanlış gibi görünen fikirleri yerleştiren bir ters nedensellik Thinkie örneği olarak görülebilir
2 yorum
Bu yorum çok iyi.
Hacker News yorumları
Ne yazık ki bu yazının vardığı sonuç biraz ters gibi görünüyor. Testleri ve örgütsel özellikleri iyileştirerek dağıtım riskini azaltmak önemli, ama işe yarayan tek yaklaşım bu değil.
Yazar, dağıtım başına değişiklik sayısının sabit olduğunu ve artırmanın zor olduğunu söylemiş; burada kastedilen “Reversie Thinkie”nin ise tam tersine dağıtım başına değişiklik sayısını azaltmak olduğunu düşünüyorum. Dağıtım toplantılarının var olma nedeni risktir; tek bir dağıtımda ne kadar çok değişiklik varsa, bug veya operasyonel sorun girme olasılığı o kadar artar. Küçük değişiklikleri sık dağıtırsanız değeri daha hızlı sunar, başarısızlıkları da daha küçük tutabilirsiniz.
Buna kanarya dağıtımı ve kademeli yayına alma eklendiğinde, dağıtım artık bir anahtarı açıp bir şeylerin bozulup bozulmaması meselesi olmaktan çıkar; arızaları performans düşüşüne veya sınırlı etkiye dönüştüren bir dünyaya geçilir. Bu yaklaşım DORA araştırmasında[0], Accelerate’te[1], The Phoenix Project’te[2] ve onun düşünsel atası The Goal’da[3] iyi ele alınır.
[0] https://dora.dev/
[1] https://www.amazon.co.uk/Accelerate-Software-Performing-Tech...
[2] https://www.amazon.co.uk/Phoenix-Project-Helping-Business-An...
[3] https://www.amazon.co.uk/Goal-Process-Ongoing-Improvement/dp...
Asıl mesele, organizasyonun otomatik testlere ne kadar zaman ve kaynak yatırdığıdır. Dağıtım öncesi ve sonrasını doğrulayacak altyapı ve başarısız değişiklikleri geri alacak altyapı olmadığı için release toplantıları ortaya çıkar; otomatik doğrulama eksikliği de geçici manuel kontrollerle kapatılır. QA organizasyonunda teknik yetkinlik eksikse, kendini korumak için manuel prosedürleri dayatır.
Daha da kötüsü, bu tür toplantılardan geçmeyi mükemmeliyetin ve en iyi uygulamanın işareti gibi sunarlar. Çünkü sorunu hafifletmek için işe alınan kişinin, o sorunu kökten ortadan kaldıracak bir teşviki yoktur. Üretim ortamına bug sızarsa bu “geliştiricilerin yarattığı ve QA’in şu ya da bu nedenle yakalayamadığı sorun” olur; oysa otomatik testler varken PR aşamasında kaçırmak bile zordur.
Toplantılar risk yüzünden değil; risk var olursa varlık nedeni oluşan ve onu azaltacak teknik beceriden yoksun roller organizasyon içinde bulunduğu için ortaya çıkar. Dağıtım sonrası değişikliğin çalıştırılıp çalışmadığına dair asgari kontroller otomatikleştirilebilir ve başarısızlıkta otomatik rollback yapılabilirse toplantılara gerek kalmaz.
Bu süreçlerin önemli bir kısmını, köklü bir çözüm yokken kötü bir duruma olabildiğince katlanmak için makul ama teknik olmayan tepkiler olarak görüyorum. Yine de tamamen zararsız değiller. Bazı organizasyonlarda, yeni projelerde veya mevcut verimsizlikleri kaldırma projelerinde bile karar vericiler insan merkezli süreçleri çözüm olarak sürekli öne sürdü.
Bu, teknik hayal gücü eksikliğinden ya da mevcut sorun çerçevesine sıkışıp kalmaktan kaynaklanıyor; bu yüzden böyle bir hayal gücüne sahip kişilerin öne çıkıp, mümkün olan yerlerde teknik değişimle insan süreçlerini en aza indirmek gerektiğini söylemesi gerekiyor. Tüm insan süreçleri teknolojiyle ortadan kaldırılamaz, ama gereksiz olanlara ince ince yayılmak istemeyiz.
Belirli bir dönemde tüm süreçlerin %2’den fazlasını değiştirmek “fazla” sayılabilir ve bu değer ayarlanabilir. Alanlara göre de değişeceğinden, ödeme işleme kodu ekibi ile İK kodu ekibinin farklı kriterleri olmalı; release’leri veya ekipleri döndürmek mantıklı olabilir.
Bu dönemde şu ekip zor işi yapar, canlıya çıkınca tekrar kolay işe döndürülür gibi. Aynı ilke siper saldırıları, tabur ilerleyişleri ve birleşik silah operasyonları için de geçerlidir.
Elbette bu bir yönetim meselesi, ama büyük ölçüde otomatikleştirilebilir; hangi ekibin hassas bir modüle yakın zamanda commit attığı gibi duyusal girdiler de yararlı olur. Son olarak bu bakış açısı, Agile/Scrum’daki sprint kavramını tuhaflaştırıyor. Bütün maratonu depar atarak koşamayacağımızı biliyoruz; peki sprintleri dönüşümlü olarak nasıl hazırlayacağız?
Feature flag kullanabilirsiniz, ama bu kez “etkinleştirilmemiş özellikler backlog’u” oluşur. Sonuçta özellikleri çoğunlukla insanlar tüketir ve insanların değişiklik konusunda eğitime ihtiyacı vardır.
O, birileri The Phoenix Project’i yazmadan çok önce akışla ilgileniyor, Toyota Production System ilkelerini çeviriyor ve fiziği iş süreçlerine uyguluyordu. The Phoenix Project’i ben de severim, ama The Goal ile karşılaştırıldığında, üretim hattı hikâyesi okuyan IT çalışanlarının “Ben PrOgrAmmEr’ım, yaratıcı işler fabrika gibi optimize edilemez” deyip kaçmamasını sağlayan ucuz bir uyarlamaya daha yakın.
Bu yüzden The Phoenix Project, The Goal’un düşünsel ardılıdır; tersi değil.
“Yazılım okuryazarlığı” kavramını açıklamaya çalışıyorum. Bugün bir şirket nasıl politika belgeleri ve e-postalar gibi İngilizce metinlerle işletilebiliyorsa, iş de kodla işletilebilir demek
Buradan “GPU işi yapıyorsa kod yazan kişi yeni yöneticidir” ya da değişiklik etkisinin net olması için şirket geneli test düzeneği gerekir gibi sonuçlar çıkıyor. Bu mükemmel yazıyla da doğrudan ilişkili görünüyor. Karar vericilerin tamamı Jira’yı ya da proje planını değil de kodu değişiklik sürecinin birinci sınıf nesnesi olarak görmüyorsa, bu karar vericiler yazılım açısından okuryazar değil demektir
“Teknik olmayan yöneticilerle bunu nasıl tartışırız?” sorusu sık sık geliyor; yanıt, tartışamazsınız. O yöneticilerin değişmesi gerekir. 30 yıl önce de bunun bir sorun olduğunu düşünüyordum ama kodcular büyüdükçe ortadan kalkacağını safça sanmıştım; devasa bir kuşak bariyeri bu. Ama bir şirketi “işletmek” için kodlama gerekmediğinden, bir gazete editörünün yazı yazamaması gibi kod yazamamak da utanılacak bir şey haline gelmeden bunu aşmak zor
Esas mesele SOP’ler, testler, toplantılar değil; iletişim olarak sistemler gibi birbirini güçlendiren yeni bir kavramlar kümesiyle işletilebilen şirketlere ihtiyaç olması
Ancak buna neden “okuryazarlık” dendiğini bilmiyorum. Maturana & Varela’nın autopoiesis terimi merkeze daha yakın; Stafford Beer’in Autopoietic Systems’ı da iyi bir düşünsel temel sağlayabilir gibi
Ama bir noktadan sonra saf yazılım “işi” zaten SaaS gibi görünmüyor mu diye düşünüyorum
Organizasyonlar dağıtımı iyileştirme girişimlerini aktif biçimde engelleyecektir. “Jenkins’i production ortamının yakınına koyamazsın”, “QA olmadan canlıya alamazsın”, “Yazılım kalitesini yeterince güvenceye almak için bu süreye ihtiyacımız var” gibi şeyleri ciddi bir yüzle söylerler
Bu sırada production hataları milyonlarcadır ve ürün kullanıcı gereksinimlerini neredeyse hiç karşılamaz. Sonuçta çoğu organizasyonda bürokrasiyle savaşmak fiilen imkânsızdır. Özellikle de bu tür toplantıları üreten 200 katmanlı yönetim tabakasının içinde değilseniz daha da öyle
Geriye iki programcı ve bir tasarımcı kadar kişi bırakıp herkesi göndermek; agile coach, product owner, scrum master, ürün uzmanı olmadan kendi kendilerine mücadele etmelerini istiyorum. Yavaş dağıtım bir sorundur ama sorunun kendisi değildir
Sürekli değiştirilemez görünen yerlere gidiyorsan, mülakatlarda bu kısmı daha çok sormalısın. Küçük şirketlerde tercihlere uygun biçimde çılgın bürokrasisi olmayan pek çok yer gördüm; şu an büyük bir şirketteyim ama tutarlı ve ikna edici şekilde hareket edince birçok şey yavaşça doğru yöne gidebiliyor
İşlerin zaman aldığını bilmek, insanların neden o hale getirdiğini anlamak ve sonra daha iyi hale getirmek için ikna edici argümanlar bulmak gerekiyor. Gerçekten kötü yerler de var; oralarda kalmamak doğru, ama umutsuzluk pek işe yaramıyor
Çözülmesi gereken çok şey olurdu ama benim önyargım bu iddiadan yana
Jenkins, yazılım geliştirme dünyasının Wordpress’idir. Yetki ayrımı olmadan eklenti çalıştıran devasa bir durum döngüsüdür. Bir Jenkins instance’ına production admin kimlik bilgilerini vermek, denetlenmemiş bir eklentiyi yazmış Romanya’daki herhangi bir kişiye root anahtarlarını vermekle aynı olabilir. Herkesin bunu istememesini gayet anlayabiliyorum
“QA olmadan canlıya alamazsın” da aynı şekilde. QA’dan hiç geçmemiş bir şeyi production’a dağıtıyorsan QA neden var? Sonradan düzeltmek için mi? Yetki vermezsen QA’in işini iyi yapma fırsatı da, yaptığı işle gurur duyma fırsatı da olmaz
Hangi inisiyatif olursa olsun ilk günden Jenkins production’a bağlanırdı; çoğu zaman doğrudan trunk-based development’a gidilirdi ve kalite tüm geliştiricilerin sorumluluğuydu. Bireysel katkıcı seviyesinde “bürokrasiyle savaş” yoktu ama dış partnerler ve paydaşlar derinden işin içinde olduğunda liderlikler arasında zaman zaman hararetli tartışmalar yaşanmış olmalı
Yalnızca programcı ve tasarımcı bırakma yöntemi benim için iyi, ama ölçeklenmez. Paydaş önceliklerini kuyruğa koyacak en az bir ürün “sahibi”, “uzmanı”, “yöneticisi” gerekir. Bu rol geliştiricilerin ve tasarımcıların sırayla taktığı bir “şapka” da olabilir, ama bazı insanlar bu beceride özellikle iyidir
Birçok organizasyonun böyle işlemediğini de anlıyorum. Bir şirketi bu yöne çevirirken, bu uygulamalara adanmış gönüllü temelli tek bir deney ekibi kurmak ve onu yukarıdan gelen yetkiyle koruyup ama yönetmemek işe yaramıştı. Tabii burası California
Biraz ilişkili bir konu: CI pipeline’ının yaklaşık 25 dakika sürdüğü, bunun 18 dakikasını 3000’den fazla unit/integration testinin yediği bir yerde çalışmıştım
Production’da ne zaman sorun çıksa daha fazla test ekliyorduk ve doğal olarak işler sarpa sardığında toparlanmak için en az 50 dakika gerekiyordu. Uzun uzun düşündükten sonra toparlanmaya odaklanmaya karar verdik; bazı testleri gevşetip basitleştirerek toplam süreyi 5 dakikanın altına indirdik ve rolling update yerine canary deployment kullandık
Bizim için gerçekten ferahlatıcı bir deneyimdi ama bazı açılardan yanlışmış gibi de hissettirdi
Elbette o dağıtım hızının içine türlü türlü unsur karışır, ama neredeyse hepsi iyi unsurlardır
Biraz konu dışı ama CloudFormation neden bu kadar yavaş?
VPC içindeki bir Lambda’yı silip EFS’e bağlı olduğu bir örnek vardı; dağıtımın kendisi oldukça hızlıydı ama CloudFormation’ın temizleyip bitirmesi yaklaşık 20 dakika sürdü
Durum değişikliklerini işlem olarak her dağıttığınızda, her adımda ön koşulları ve son koşulları doğrulamak gerekir. Birbirine az da olsa bağımlılığı olan bir değişiklik kümesini yayımlamak istiyorsanız, her değişikliği sıralı adımlar halinde dağıtmaktan başka çare yoktur. Her adım değişikliği uygulamak, doğrulamak ve durumu yoklamak için birden fazla ağ çağrısı yapar; her biri yaklaşık 50–200 ms sürer ve hızla birikir
Aynı uygulamayı Terraform veya Ansible ile başka bir bulut sağlayıcısına dağıtsanız da benzer sonuçlar çıkar. Aynı değişikliği elle dağıtmak ise birkaç dakikalık işi bir günlük eziyete dönüştürür
IaC’nin en büyük sorunu, fazla yüksek seviyeli olması ve içeride çok fazla iş yapması; bu yüzden hangi değişikliğin gerçekten uygulandığını ya da ne yaptığını bilmeyen insanlar ortaya çıkıyor. Sonra da uzun sürüyor diye şikâyet ediyorlar
İş hayatımda kişisel olarak yaşadığım bir şey var. Noel tatilinden önce büyük bir değişiklik vardı ve ciddi bir korku hakimdi. Organizasyon buna testleri artırarak, yani regresyon testlerini artırıp ek yükü büyüterek karşılık verdi
Bu da dev’deki bir değişikliğin benim branch’imdeki değişiklikleri bozma riskini artırdı. Bu, kod merge çakışması değil, karmaşık uyarlanabilir sistemler açısından bir riskti. Ben bu riske karşı toplantı oluşturdum ve proje takvimini duyururken, PR’lara kod stili yorumları bırakırlarsa bunların sonraki PR’a erteleneceğini ve sonunda göz ardı edileceğini ekip arkadaşlarıma beklenti olarak anlattım
Asıl gereken, bileşenler arası izolasyonu daha iyi olan daha ince taneli testlerdi. Sorun şu ki yönetim çok yüksek seviyeden bakıyor ve toplantıları bir araç değil, kendi başına ulaşılmaya değer bir hedef olarak görüyor. Toplantı çoksa iş birliği çoktur, o da iyidir gibi. Teknik olmayan yönetimle birlikte teknik değişimi nasıl yöneteceğimize dair tavsiyeler görmek isterim
İlgili yazı: Slow Deployment Causes Meetings - https://news.ycombinator.com/item?id=10622834 - Kasım 2015, 26 yorum
Mikroservis kullanırsanız dağıtım sıklığını da yatay olarak ölçekleyebilirsiniz
Bağımsız modüllerden oluşan monolitik bir uygulamayla da mikroservis olmadan aynı ölçüde dağıtım yapabilirsiniz; üstelik altyapı/CI·CD karmaşıklığı veya uygulama içi fonksiyon çağrılarını kırılgan dağıtık sistem iletişimi problemine dönüştürmek gibi başlıca dezavantajlardan kaçınabilirsiniz. Gereksiz tesadüfi karmaşıklığa direnmek gerekir
[1] https://www.fearofoblivion.com/build-a-modular-monolith-firs...
[2] https://ardalis.com/introducing-modular-monoliths-goldilocks...
Bir de dağıtım planlaması ve özellik yayına alma senkronizasyonu gibi eğlenceli yeni bir sorun ortaya çıkıyor
Aksi halde dağıtık veri problemini ve daha fazla karmaşıklık katmanını, yani monolitten daha fazla toplantıyı aynı anda elde edersiniz
Monolitte SOLID, DRY ve diğer “clean code” tarzı saçmalıkların devasa karmaşası içinde, kimsenin bir şeyi değiştirirse kırılacak diye dokunamadığı bir duruma düşme riski var. Nesne yönelimli ilkelerin kendisinin yüzeyde yanlış olduğu anlamına gelmez ama çoğu zaman o kadar aşırı belirsizler ki kimse doğru düzgün uygulayamıyor
Uncle Bob’un her eleştiri geldiğinde “ilkeleri yanlış anlamışlar” diye geçiştirmesi beni hep güldürüyor. Bu kadar çok insan yanılıyorsa, belki de ilkeler kötüdür? Mikroservisler de kötü yönetişimden korumaz; sadece sorunlar başka biçimde ortaya çıkar. Birden fazla mikroservis kurup hangi değişikliğin diğer servislere nasıl etki ettiğini kimsenin bilmediği bir duruma gelmek bence çok kolay ve çok yaygın
Sonuçta bu bir ekip yönetimi sorunu ve deneyimime göre sektörümüzün en kötü olduğu alan. “Team Topologies” gibi yeni nesil yaklaşımlar gelirse daha iyi olur, ama gerçekten sona erse bile onlarca yıl sürer. Kuruluş “IT”yi yalnızca maliyet merkezi olarak görür ve yazılım mühendisliği en iyi uygulama süreçlerine dahil edilebilecek şekilde talepte bulunmazsa, çoğu zaman dijitalleşme biriminin kontrolünden de çıkar
Genel amaçlı bir dil olarak Goyu sevmemin nedenlerinden biri, tasarım gereği basit olması ve çoğu zaman değiştirmesi kolay kod tabanlarına yol açması. Go’ya geçerek işin gerçekten ihtiyaç duyduğu şeyleri teslim edebilir hale gelen ve bu sayede büyüyen birkaç online banka ve kiralama/varlık yönetimi platformu gördüm. Buna karşılık rakipleri hantal Java veya C# kod tabanlarına sıkışmıştı; şanslılarsa altı ayda bir hatalarla dolu bir özellik çıkarabiliyorlardı
Bu Go, Java ya da C#’ın kendi meselesi değil; eski usul nesne yönelimli mimari ve tasarımın bozmanın çok kolay olmasıyla ilgili. Eskiden çalıştığım bir yerde binden fazla C# interface’i vardı ve hiçbir interface iki ya da daha fazla sınıf tarafından tüketilmiyordu. On binlerce interface’in hepsi aynı klasör ve namespace içindeydi; gerekeni bulmak için şans dilemek gerekiyordu. Go’da ya da herhangi bir dilde de bunu yapabilirsiniz ama eski nesne yönelimli clean code dil kültüründe değilseniz bunu yapma olasılığınız daha düşük. Özellikle C#’ta varsayılan soyutlama kültüre o kadar derin işlemiş ki yapmamak daha zor
Kişisel olarak Python organizasyonlarına gizli bir sevgim var. Her zaman hızlı teslim ederler ve kod berbat olur. Çok sevimli
Büyük ölçüde doğru, ama bir o kadar da konuyla ilgisiz
Özetle, önemli olan yalnızca yazılım performansı, dolayısıyla insan performansıdır. Risk yönetimi ve risk kabulü sayılarla ölçülebilir. Yazılımda bu, diğer mesleklere göre çok daha basittir; çünkü yazılım mühendisleri yalnızca bilinen operasyonel kısıtlar içinde risk kabul edebilir, geri kalan her şey ertelenir
Daha hızlı olmak istiyorsanız, her şeyden önce insan yineleme sıklığını en üst düzeye çıkarmalısınız. Yetki beklediğiniz için yineleme yapamıyorsanız tıkanmışsınız demektir; derlemeyi ya da ekran yenilemeyi bekliyorsanız yavaşlamışsınız demektir. Bu da sayılarla ölçülebilir
A, B’den 100 kat daha hızlı yineleme yapabiliyorsa doğruluk ikincil hale gelir. B yavaş olduğu için doğruluğu maksimize etmek zorundadır. A ise öğrenmek, başarısız olmak ve iyileşmek için aşırı bir esnekliğe sahiptir; böylece hem daha hızlı hem de daha doğru hale gelir
Daha hızlı yineleme yaparken riski azaltmanın bir parçası da hızlı test otomasyonudur. A, 4 insan yinelemesi süresinde %90’dan fazla test kapsamını çalıştırabiliyorsa, bu test otomasyonu B’nin tek bir yinelemesinden hâlâ 25 kat hızlıdır ve regresyon riski %90’dan fazla daha düşüktür
Hızlı dağıtım, arıza müdahale savaş odaları yaratır
Bu azalmadan çok daha önemli olan şey, bir sorun çıktığında nedenini bulma hızının çok daha artmış olmasıydı. Geri alınan değişiklikler çok az olduğu için rollback yapmak da çok daha güvenli ve kolaydı. Kimse 3 haftalık işi geri almak istemez. Bu kaostur