Yazma Kurallarının Zorlukları

Sorun bildir Kaynağı göster Gece · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Bu sayfa, belirli sorunlar ve zorluklarla ilgili üst düzey bir genel bakış sunar etkili Bazel kurallarından sorumlu olacaksınız.

Özet Şartlar

  • Varsayım: Doğruluk, İşleme Hızı, Kullanım Kolaylığı ve Gecikme
  • Varsayım: Büyük Ölçekli Depolar
  • Varsayım: BUILD benzeri Açıklama Dili
  • Geçmiş: Yükleme, Analiz ve Yürütme Arasındaki Kesin Ayrım Güncel ancak API'yi etkilemeye devam ediyor
  • Doğal: Uzaktan Yürütme ve Önbelleğe Alma Zordur
  • İçsel: Doğru ve Hızlı Artımlı Derlemeler İçin Değişim Bilgilerini Kullanma Olağandışı Kodlama Kalıpları gerektiriyor
  • İçsel: İkinci dereceden zamandan ve bellek tüketiminden kaçınmak Zor

Varsayımlar

Derleme sistemi hakkında yapılan bazı varsayımlar, doğruluk, kullanım kolaylığı, işleme hızı ve büyük ölçekli depolar. İlgili içeriği oluşturmak için kullanılan aşağıdaki bölümlerde bu varsayımlar ele alınmaktadır ve müşterinin ihtiyaçlarını etkili bir şekilde yazılmasını sağlar.

Doğruluk, işleme hızı, kullanım kolaylığı ve gecikme

Derleme sisteminin, sistemle ilgili her şeyden önce ve iyi bir fırsattır. Belirli bir kaynak ağacın çıktısı çıkış ağacının görünümünden bağımsız olarak aynı derleme her zaman aynı olmalıdır. beğeniyor. İlk tahminde bu, Bazel'in her bir ayrıntıyı bilmesi gerektiği anlamına gelir. herhangi bir derleme adımına giden, bu adımı yeniden çalıştırabilecek bir giriş girişlerin değişmesini sağlar. Sızdırdığı için Bazel'in doğru şekilde üretilmesiyle ilgili sınırlamalar var tarihi / saati gibi bazı bilgileri verir ve belirli türdeki dosya özelliklerinde yapılan değişiklikler gibi değişiklikler olabilir. Korumalı alan bildirilmemiş giriş dosyalarının okunmasını engelleyerek doğruluğun sağlanmasına yardımcı olur. Ayrıca bilinen birkaç doğruluk sorunu vardır, ve bunların çoğu, ikisi de zor olan Fileset veya C++ kurallarıyla ilgilidir neden olabilir. Bu sorunları düzeltmek için uzun vadeli çalışmalar yapmaktayız.

Derleme sisteminin ikinci hedefi, yüksek işleme hızına sahip olmaktır. biz devamlı olarak, projenin devamı içinde yapılabileceklerin makine tahsisi anlamına gelir. Uzaktan yürütme hizmet aşırı yüklendiğinden kimse işlerini tamamlayamaz.

Kullanım kolaylığı geliyor. Aynı (veya uzaktan yürütme hizmetinin yerleşkesini görmek için daha kolay kullanılır.

Gecikme, bir derlemenin başlatılmasından istenen sonuca ulaşmaya kadar geçen süreyi belirtir Bu, başarılı veya başarısız bir teste ait test günlüğü ya da hata mesajı olabilir. BUILD dosyasında yazım hatası olduğunu belirten bir ileti görürsünüz.

Bu hedeflerin genellikle çakıştığını unutmayın; gecikme, işleme hızının bir fonksiyonudur. olarak, kullanım kolaylığı açısından doğrulukla örtüşmelidir.

Büyük ölçekli depolar

Derleme sisteminin, büyük çaplı kod depoları düzeyinde, tek bir sabit diske sığmayacağı için bu, onun Neredeyse tüm geliştirici makinelerinde tam ödeme yapma. Orta boyutlu bir yapı on binlerce BUILD dosyasını okuyup ayrıştırması ve küçük bir gezegen. Teorik olarak mümkün olsa da BUILD dosyalarını tek bir makinede barındırıyor. Henüz bu işlemi tek bir makinede gerçekleştiremedik yeterli zaman ve belleğe sahip olmalıdır. Bu nedenle, BUILD dosyalarının bağımsız olarak yüklenip ayrıştırılabilir.

DERLEME benzeri bir açıklama dili

Bu bağlamda, en az 24 saat uzunluğunda Kitaplık ve ikili program kurallarındaki BUILD dosyalarına hemen hemen benzer ve birbirlerine bağımlılıklarını konuşacağız. BUILD dosyaları bağımsız olarak okunup ayrıştırılabilir ve mümkün olduğunda kaynak dosyalara bakmaktan bile kaçınıyoruz (yalnızca varlık).

Tarihi

Bazel sürümleri arasında zorluklara neden olan bazı farklar vardır. edinilen bilgiler aşağıdaki bölümlerde özetlenmiştir.

Yükleme, analiz ve yürütme arasındaki kesin ayrım eski olsa da API'yi etkilemeye devam eder

Teknik olarak bir kuralın giriş ve çıkış dosyalarını bilmesi için uzaktan yürütmeye gönderilmeden hemen önce bir işlem yapılması gerekir. Ancak orijinal Bazel kod tabanı, paketleri yükleme konusunda sıkı bir ayrım uyguluyordu, daha sonra Bir yapılandırma kullanarak kuralları analiz etme (esasen komut satırı işaretleri) ve herhangi bir işlem yapması gerekir. Bu ayrım hâlâ rules API'sinin bir parçasıdır dayanıyor. (Aşağıda daha ayrıntılı bilgi verilmiştir.)

Bu nedenle, rules API için kuralın bildirim temelli bir açıklaması gerekir. arayüzü (neleri olduğu, özellik türleri). RACI matrisinde özel kodların çalıştırılmasına izin verdiği durumlara örnek olarak verilebilir. çıkış dosyalarının örtülü adlarını ve özelliklerin örtülü değerlerini hesaplayabilir. Örneğin, örneğin, "foo" adında bir java_library kuralı dolaylı olarak "libfoo.jar", derleme grafiğindeki diğer kurallarda referans alınabilir.

Ayrıca, bir kuralın analizi kaynak dosyaları okuyamaz veya bir eylemin çıktısı; bunun yerine kısmi yönlendirilmiş iki taraflı yalnızca kurala göre belirlenen derleme adımlarının ve çıkış dosya adlarının grafiği ve bağımlılıklarını anlamasına yardımcı olur.

Yerleşik

Kuralların yazılmasını zorlaştıran doğal nitelikler vardır. en yaygın olanlardan bazıları aşağıdaki bölümlerde açıklanmıştır.

Uzaktan yürütme ve önbelleğe alma sabittir

Uzaktan yürütme ve önbelleğe alma büyüklük yaklaşık iki kat daha büyüktür. üretiliyor. Ancak, performans göstermesi gereken ölçek şaşırtıcıdır: Google'ın uzaktan yürütme hizmeti, her bir kullanıcı için çok sayıda gerekir, ayrıca protokol gereksiz tekrarlardan kaçınmak için hem de hizmet tarafında gereksiz işler yapar.

Şu anda protokol, derleme sisteminin karar vermeniz gerekir. derleme sistemi, daha sonra bu işlemden sonra izin verir ve planlayıcıdan önbellek isabeti ister. Bir önbellek isabeti bulunursa planlayıcı, çıkış dosyalarının özetleriyle yanıt verir; dosyaların kendisi daha sonra özetlenir. Ancak, bu değişiklik Bazel'e yönelik kısıtlamalar tüm giriş dosyalarını önceden bildirmesi gerekir.

Doğru ve hızlı artımlı derlemeler için değişiklik bilgilerini kullanmak, olağan dışı kodlama kalıpları gerektirir.

Yukarıda, Bazel'in doğru olması için, öncelikle yapılması gerekenleri derleme adımının başarıyla tamamlanıp tamamlanmadığını belirlemek için hâlâ güncel durumda. Aynı durum paket yükleme ve kural analizi için de geçerlidir. Skyframe'i, bunu işleyecek ve emin olabilirsiniz. Skyframe bir grafik kitaplığı ve değerlendirme çerçevesidir hedef düğümünü (örneğin, "build //foo with this options" (bu seçeneklerle //foo oluştur) gibi) ve bunu daha sonra değerlendirilip birleştirilir. Bu, toplamda yardımcı olur. Skyframe, bu işlemin bir parçası olarak paketleri okur, kuralları analiz eder , işlemleri yürütür.

Skyframe, her düğümde belirli bir düğümün hesaplama yapmak için tam olarak hangi düğümleri kullandığını izler , hedef düğümünden giriş dosyalarına kadar (bu işlemler sırasında) Skyframe düğümleri de yer alır). Bu grafiğin bellekte açıkça temsil edilmesini sağlama Böylece, derleme sistemi belirli bir değerden tam olarak hangi düğümlerin giriş dosyasına değiştirme (giriş dosyasının oluşturulması veya silinmesi dahil), ve çıktı ağacını amaçlanan durumuna geri yüklemek için gereken minimum çalışma miktarını ifade eder.

Bunun bir parçası olarak her düğüm, bir bağımlılık keşfi süreci yürütür. Her biri bağımlılıkları tanımlayabilir ve ardından bu bağımlılıkların içeriğini kullanabilir başka bağımlılıkları da açıklayabilirsiniz. Prensipte, bu yaklaşım düğüm başına iş parçacığı modelidir. Ancak orta boyutlu derlemelerde yüzlerce Mevcut Java ile kolayca mümkün olmayan binlerce Skyframe düğümü teknolojisidir (ve tarihsel nedenlerden dolayı şu anda Java'yı kullanmak zorundayız, bu nedenle basit ileti dizileri ve devamlı öğeler içermez.

Bazel bunun yerine sabit boyutlu bir iş parçacığı havuzu kullanır. Ancak bu, bir düğümün henüz mevcut olmayan bir bağımlılığın bildirildiği durumlarda, bu bağımlılığı iptal etmemiz gerekebilir. bağımlı bir iş parçacığı olduğunda yeniden başlatın (muhtemelen başka bir iş parçacığında kullanılabilir. Dolayısıyla, düğümler bu işlemi çok fazla yapmamalıdır. CANNOT TRANSLATE seri olarak N bağımlılığı bildiren düğüm, N kez yeniden başlatılabilir. O(N^2) süresine mal olur. Bunun yerine, sözleşmenin önceden toplu olarak Bu da bazen kodun yeniden düzenlenmesini, hatta her parçanın bir yeniden başlatma sayısını sınırlamak için bir düğümü birden çok düğüme bağlayabilirsiniz.

Bu teknolojinin şu anda rules API'sinde kullanılamadığını unutmayın. bunun yerine kuralları API'si hâlâ yükleme, analiz ve güvenlik gibi eski kavramlar kullanılarak farklı aşamaları vardır. Ancak temel kısıtlamalardan biri, diğer düğümlerin çerçeveden geçmesi gerekir. Böylece, bağımlılıkları ortaya koyabilir. Derleme sisteminin kullandığı dilden bağımsız olarak kuralların yazıldığından emin olun (bunların, uygulamanızın aynı), kural yazarları bu yöntemi atlayan standart kitaplıklar veya kalıplar kullanmamalıdır Gökyüzü çerçevesi. Java için bunun anlamı, java.io.File dosyasının yanı sıra içeren bir kitaplıktan da yararlanır. Bağımlılığı destekleyen kitaplıklar ekleme işleminin yine de bu alt düzey arayüzlerin doğru şekilde ayarlanması Gökyüzü çerçevesi.

Bu, kural yazarlarının tam bir dil çalışma zamanına maruz kalmasını önlemenizi önemle tavsiye eder. en başta sunun. Bu tür API'lerin yanlışlıkla kullanılma riski çok büyüktür - geçmişteki bazı Bazel hataları, güvenli olmayan API'ler kullanan kurallardan kaynaklanmıştı. ancak kurallar Bazel ekibi veya diğer alan uzmanları tarafından yazılmış olsa bile.

İkinci dereceden zaman ve bellek tüketiminden kaçınmak zordur

Skyframe'in getirdiği zorunluluklar bir yana, Skyframe'in zorunlu tuttuğu Java'yı kullanmanın geçmişteki kısıtlamaları ve kuralları API'sinin eskiliği, yanlışlıkla ikinci dereceden zaman veya hafıza tüketimine neden olmak, kitaplık ve ikili program kurallarına dayalı herhangi bir derleme sistemindeki problemdir. İki tür ikinci dereceden bellek tüketimine neden olan (ve dolayısıyla ikinci dereceden zaman tüketimi).

  1. Kitaplık Kural Zincirleri - A'nın B'ye, C'ye bağlı ve bu şekilde devam eder. Ardından, alanın geçişli kapanması üzerinden bazı özellikleri veya JavaScript'in çalıştırıldığı C++ linker komutu gibi kullanabilirsiniz. Naif olarak, standart bir liste uygulaması alabiliriz; ancak, Bu da ikinci dereceden bellek tüketimini zaten beraberinde getiriyor: ilk kitaplık. ve bu girişlerin her biri sınıf yolunda bir giriş, ikinci iki, üçüncü üçünü ve her ikisine de aynı değeri katar.

  2. Aynı Kitaplık Kurallarına Bağlı İkili Program Kuralları: Aynı kitaplığa bağımlı bir ikili program kümesinin (örneğin, aynı testte veya belirli bir videoda kitaplık koduna sahiptir. N kuraldan kuralların yarısının ikili kurallar olduğunu ve kitaplığının diğer yarısına da uyduğundan emin olun. Şimdi her ikili programın, kitaplık kurallarının geçişli olarak kapatılması üzerinden hesaplanan bazı özellikler; örneğin, veya C++ bağlayıcı komut satırını kullanarak dosyaları geçici olarak düzenleyebilirsiniz. Örneğin, C++ bağlantı işleminin komut satırı dizesi gösterimini genişletebilir. Yok N/2 öğelerinin kopyaları O(N^2) bellektir.

İkinci dereceden karmaşıklığı önlemek için özel koleksiyon sınıfları

Bazel, bu iki senaryodan çok etkileniyordu. O yüzden, ekibimle birlikte bellekteki bilgileri etkili bir şekilde sıkıştıran özel koleksiyon sınıfları her adımda kopyalamayın. Bu veri yapılarının neredeyse hepsi, anlambilim, yani depset (dahili uygulamada NestedSet olarak da bilinir). Çoğu son birkaç yılda Bazel'ın bellek tüketimini azaltmaya yönelik depset'leri kullanacak şekilde yeniden düzenlemelidir.

Maalesef, Depsets kullanımı tüm sorunları otomatik olarak çözmüyor; Özellikle, her kuralın yeniden ekleme işleminde bir düşüş üzerinde yineleme bile ikinci dereceden zaman tüketimi. NestedSets'in kendi içinde bazı yardımcı yöntemleri de vardır. Normal koleksiyon sınıflarıyla birlikte çalışabilirliği kolaylaştırmak; maalesef, NestedSet'i bu yöntemlerden birine yanlışlıkla iletmek, ve ikinci dereceden bellek tüketimini yeniden başlatır.