Kalıcı Çalışanlar Oluşturma

Sorun bildirme Kaynağı görüntüleme Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Kalıcı çalışanlar, derlemenizi hızlandırabilir. Derlemenizde, yüksek başlangıç maliyeti olan veya işlemler arası önbelleğe alma özelliğinden yararlanabilecek tekrarlanan işlemleriniz varsa bu işlemleri gerçekleştirmek için kendi kalıcı işleyicinizi uygulamak isteyebilirsiniz.

Bazel sunucusu, stdin/stdout kullanarak işleyiciyle iletişim kurar. Protokol arabelleklerinin veya JSON dizelerinin kullanımını destekler.

İşçi uygulaması iki bölümden oluşur:

Çalışanı oluşturma

Kalıcı çalışanlar birkaç koşulu karşılar:

  • stdin kaynağından WorkRequests dosyasını okur.
  • WorkResponses (ve yalnızca WorkResponse öğeleri) stdout alanına yazılır.
  • --persistent_worker işaretini kabul eder. Sarmalayıcı, --persistent_worker komut satırı işaretini tanımalıdır ve yalnızca bu işaret iletildiyse kendini kalıcı hale getirmelidir. Aksi takdirde tek seferlik bir derleme yapmalı ve çıkmalıdır.

Programınız bu koşulları karşılıyorsa kalıcı bir işleyici olarak kullanılabilir.

İş istekleri

WorkRequest, işçiye gönderilecek bağımsız değişkenler listesini, işçinin erişebileceği girişleri temsil eden yol-özet çiftleri listesini (bu zorunlu değildir ancak bu bilgileri önbelleğe alma için kullanabilirsiniz) ve tek kanallı işçiler için 0 olan bir istek kimliğini içerir.

NOT: Protokol arabelleği spesifikasyonunda "alt tireli" (request_id) kullanılırken JSON protokolünde "üst tireli" (requestId) kullanılır. Bu dokümanda, JSON örneklerinde üst tireli, protokolden bağımsız olarak alandan bahsederken ise alt tireli kullanılır.

{
  "arguments" : ["--some_argument"],
  "inputs" : [
    { "path": "/path/to/my/file/1", "digest": "fdk3e2ml23d"},
    { "path": "/path/to/my/file/2", "digest": "1fwqd4qdd" }
 ],
  "requestId" : 12
}

İsteğe bağlı verbosity alanı, çalışandan ek hata ayıklama çıkışı istemek için kullanılabilir. Nelerin ve nasıl yayınlanacağı tamamen çalışana bağlıdır. Daha yüksek değerler daha ayrıntılı çıkış anlamına gelir. --worker_verbose işaretçisi Bazel'e iletildiğinde verbosity alanı 10 olarak ayarlanır ancak farklı çıkış miktarları için manuel olarak daha küçük veya daha büyük değerler kullanılabilir.

İsteğe bağlı sandbox_dir alanı yalnızca çoklu korumalı alan özelliğini destekleyen çalışanlar tarafından kullanılır.

İş yanıtları

WorkResponse, bir istek kimliği, sıfır veya sıfır olmayan bir çıkış kodu ve isteği işleme veya yürütme sırasında karşılaşılan hataları açıklayan bir çıkış mesajı içerir. Çalışan, çağırdığı tüm araçların stdout ve stderr değerlerini yakalamalı ve WorkResponse üzerinden bildirmelidir. İşçi protokolünü etkileyeceğinden, işçi işleminin stdout alanına yazmak güvenli değildir. Çalışan işleminin stderr alanına yazmak güvenlidir ancak sonuç, bağımsız işlemlere atanmak yerine çalışan başına bir günlük dosyasında toplanır.

{
  "exitCode" : 1,
  "output" : "Action failed with the following message:\nCould not find input
    file \"/path/to/my/file/1\"",
  "requestId" : 12
}

Protobuf'lar için geçerli olan kural uyarınca tüm alanlar isteğe bağlıdır. Ancak Bazel, WorkRequest ve ilgili WorkResponse'nin aynı istek kimliğine sahip olmasını gerektirir. Bu nedenle, sıfırdan farklıysa istek kimliği belirtilmelidir. Bu geçerli bir WorkResponse.

{
  "requestId" : 12,
}

0 değerine sahip bir request_id, "tek kanallı" bir isteği gösterir. Bu istek, diğer isteklerle paralel olarak işlenemediği durumlarda kullanılır. Sunucu, belirli bir çalışanın yalnızca request_id 0 veya yalnızca request_id sıfırdan büyük olan istekler aldığını garanti eder. Tek kanallı istekler seri olarak gönderilir. Örneğin, sunucu bir yanıt alana kadar başka bir istek göndermez (iptal istekleri hariç, aşağıya bakın).

Notlar

  • Her protokol arabelleğinin önünde varint biçiminde uzunluğu yer alır (MessageLite.writeDelimitedTo() bölümüne bakın).
  • JSON isteklerinin ve yanıtlarının önünde bir boyut göstergesi yoktur.
  • JSON istekleri, protobuf ile aynı yapıyı korur ancak standart JSON'u kullanır ve tüm alan adları için büyük/küçük harf kullanımına uyar.
  • protobuf ile aynı geriye dönük ve ileriye dönük uyumluluk özelliklerini korumak için JSON işleyicilerinin bu mesajlardaki bilinmeyen alanları tolere etmesi ve eksik değerler için protobuf varsayılanlarını kullanması gerekir.
  • Bazel, istekleri protobuf olarak depolar ve protobuf'in JSON biçimini kullanarak JSON'a dönüştürür.

İptal

Çalışanlar isteğe bağlı olarak iş isteklerinin tamamlanmadan önce iptal edilmesine izin verebilir. Bu, özellikle yerel yürütmenin daha hızlı bir uzak yürütme tarafından düzenli olarak kesintiye uğratılabileceği dinamik yürütmeyle bağlantılı olarak faydalıdır. İptale izin vermek için execution-requirements alanına supports-worker-cancellation: 1 ekleyin (aşağıya bakın) ve --experimental_worker_cancellation işaretini ayarlayın.

İptal isteği, cancel alanının ayarlandığı bir WorkRequest'dir (benzer şekilde iptal yanıtı, was_cancelled alanının ayarlandığı bir WorkResponse'dir). İptal isteğinde veya iptal yanıtında bulunması gereken tek diğer alan, hangi isteğin iptal edileceğini belirten request_id alanıdır. request_id alanı, tek kanallı çalışanlar için 0 olur veya çok kanallı çalışanlar için daha önce gönderilen bir WorkRequest'un 0 olmayan request_id değeri olur. Sunucu, işleyicinin daha önce yanıtladığı istekler için iptal istekleri gönderebilir. Bu durumda iptal isteği yoksayılmalıdır.

İptal edilmeyen her WorkRequest mesajı, iptal edilip edilmediğine bakılmaksızın tam olarak bir kez yanıtlanmalıdır. Sunucu bir iptal isteği gönderdikten sonra işleyici, request_id ayarlanmış ve was_cancelled alanı doğru olarak ayarlanmış bir WorkResponse ile yanıt verebilir. Normal bir WorkResponse göndermek de kabul edilir ancak output ve exit_code alanları yoksayılır.

Bir WorkRequest için yanıt gönderildikten sonra işleyici, çalışma dizinindeki dosyalara dokunmamalıdır. Sunucu, geçici dosyalar da dahil olmak üzere dosyaları temizleyebilir.

İşleyiciyi kullanan kuralı oluşturma

Ayrıca, çalışan tarafından gerçekleştirilecek işlemleri oluşturan bir kural oluşturmanız gerekir. İşçi kullanan bir Starlark kuralı oluşturmak, başka bir kural oluşturmaya benzer.

Ayrıca, kuralın işçiye referans vermesi gerekir ve ürettiği işlemler için bazı koşullar vardır.

Çalışana atıfta bulunma

Çalışanı kullanan kuralın, çalışanın kendisine atıfta bulunan bir alan içermesi gerekir. Bu nedenle, çalışanınızı tanımlamak için bir \*\_binary kuralı örneği oluşturmanız gerekir. Çalışanınızın adı MyWorker.Java ise ilişkili kural şu olabilir:

java_binary(
    name = "worker",
    srcs = ["MyWorker.Java"],
)

Bu işlem, çalışan ikilisini belirten "worker" etiketini oluşturur. Ardından, işçiyi kullanan bir kural tanımlarsınız. Bu kural, çalışan ikilisine atıfta bulunan bir özellik tanımlamalıdır.

Oluşturduğunuz çalışan ikili dosyası, derlemenin en üst düzeyinde bulunan "work" adlı bir paketteyse özellik tanımı şöyle olabilir:

"worker": attr.label(
    default = Label("//work:worker"),
    executable = True,
    cfg = "exec",
)

cfg = "exec", işleyicinin hedef platform yerine yürütme platformunuzda çalışacak şekilde oluşturulması gerektiğini gösterir (yani işleyici, derleme sırasında araç olarak kullanılır).

İş işlemi şartları

Çalışanı kullanan kural, çalışanın gerçekleştireceği işlemleri oluşturur. Bu işlemler için birkaç koşul vardır.

  • "arguments" alanı. Bu işlev, bir dize listesi alır. Bu listenin son öğesi hariç tümü, başlangıçta işçiye iletilen bağımsız değişkenlerdir. "arguments" listesindeki son öğe, flag-file (@ işareti ile başlayan) bağımsız değişkendir. Çalışanlar, WorkRequest başına belirtilen işaret dosyasından bağımsız olarak bağımsız değişkenleri okur. Kuralınız, çalışan için başlangıç dışı bağımsız değişkenleri bu işaret dosyasına yazabilir.

  • "supports-workers" : "1", "supports-multiplex-workers" : "1" veya her ikisini içeren bir sözlük alan "execution-requirements" alanı.

    "arguments" ve "execution-requirements" alanları, çalışanlara gönderilen tüm işlemler için gereklidir. Ayrıca, JSON çalışanları tarafından yürütülmesi gereken işlemlerin yürütme koşulları alanına "requires-worker-protocol" : "json" eklenmesi gerekir. "requires-worker-protocol" : "proto", geçerli bir yürütme koşuludur ancak varsayılan oldukları için proto çalışanlar için gerekli değildir.

    Yürütme koşullarında da bir worker-key-mnemonic ayarlayabilirsiniz. Bu, yürütülebilir dosyayı birden fazla işlem türü için yeniden kullanıyorsanız ve işlemleri bu işleyiciye göre ayırt etmek istiyorsanız yararlı olabilir.

  • İşlem sırasında oluşturulan geçici dosyalar, işleyicinin dizinine kaydedilmelidir. Bu, korumalı alanı etkinleştirir.

Yukarıda açıklanan "işçi" özelliğine sahip bir kural tanımı varsayımıyla, girişleri temsil eden bir "srcs" özelliği, çıkışları temsil eden bir "output" özelliği ve işçi başlangıç bağımsız değişkenlerini temsil eden bir "args" özelliğinin yanı sıra ctx.actions.run çağrısı şöyle olabilir:

ctx.actions.run(
  inputs=ctx.files.srcs,
  outputs=[ctx.outputs.output],
  executable=ctx.executable.worker,
  mnemonic="someMnemonic",
  execution_requirements={
    "supports-workers" : "1",
    "requires-worker-protocol" : "json"},
  arguments=ctx.attr.args + ["@flagfile"]
 )

Başka bir örnek için Kalıcı çalışanları uygulama başlıklı makaleyi inceleyin.

Örnekler

Bazel kod tabanı, entegrasyon testlerimizde kullanılan örnek JSON işleyicisinin yanı sıra Java derleyici işleyicileri kullanır.

Doğru geri çağırma işlevini göndererek Java tabanlı herhangi bir aracı işçiye dönüştürmek için iskelelerini kullanabilirsiniz.

Çalışan kullanan bir kural örneği için Bazel'in çalışan entegrasyon testine göz atın.

Harici katkıda bulunanlar, çalışanları çeşitli dillerde uyguladı. Bazel kalıcı çalışanlarının çok dilli uygulamalarını inceleyin. GitHub'da daha birçok örnek bulabilirsiniz.