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

Sorun bildir Kaynağı göster

Kalıcı çalışanlar derlemenizi hızlandırabilir. Derlemenizde, yüksek başlatma maliyeti olan veya işlemler arası önbelleğe alma işleminden fayda sağlayacak tekrarlanan işlemler varsa bu işlemleri gerçekleştirmek için kendi kalıcı çalışanınızı uygulamak isteyebilirsiniz.

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

Çalışan uygulamasının iki bölümü vardır:

Çalışanı yapma

Israrcı bir çalışan birkaç şartı karşılar:

  • stdin öğesinde WorkRequests yazar.
  • stdout cihazına WorkResponses (ve yalnızca WorkResponse) yazar.
  • --persistent_worker işaretini kabul eder. Sarmalayıcı, --persistent_worker komut satırı işaretini tanımalı ve yalnızca bu işaret geçilirse kendini kalıcı hale getirmelidir. Aksi takdirde, tek seferlik derleme yapıp çıkış yapması gerekir.

Programınız bu gereklilikleri karşılıyorsa ısrarlı bir çalışan olarak kullanılabilir.

İş istekleri

WorkRequest, çalışanın bağımsız değişken listesini, çalışanın erişebileceği girişleri temsil eden yol-özet çiftlerinin bir listesini (bu zorunlu kılınmamıştır ancak bu bilgiyi önbelleğe alma için kullanabilirsiniz) ve tek yönlü çalışanlar için 0 olan bir istek kimliğini içerir.

NOT: Protokol arabelleği spesifikasyonu "yılan kılıfı" (request_id) kullanırken JSON protokolü "deve kılıfı" (requestId) kullanır. Bu belgede JSON örneklerinde deve düzeni kullanılmaktadır, ancak protokolden bağımsız olarak alan hakkında konuşurken yılan durumu kullanılmaktadı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. Neyin nasıl çıkacağı tamamen çalışana bağlıdır. Daha yüksek değerler, daha ayrıntılı çıktıyı belirtir. --worker_verbose işaretini Bazel'a ilettiğinizde verbosity alanı 10 olarak ayarlanır. Ancak daha küçük veya daha büyük değerler, farklı miktarlarda çıktılar için manuel olarak kullanılabilir.

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

İş yanıtları

WorkResponse; istek kimliği, sıfır veya sıfır olmayan bir çıkış kodu ve isteğin işlenmesinde veya yürütülmesinde karşılaşılan hataları açıklayan bir çıkış dizesi içerir. output alanı, kısa bir açıklama içerir. Tam günlükler, çalışanın stderr koduna yazılabilir. Çalışanlar yalnızca stdout öğesine WorkResponses yazabileceğinden, çalışanın kullandığı araçların stdout öğelerini stderr öğesine yönlendirmesi yaygın bir durumdur.

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

Protobufs standardına göre tüm alanlar isteğe bağlıdır. Bununla birlikte, Bazel, WorkRequest ve karşılık gelen WorkResponse değerlerinin aynı istek kimliğine sahip olmasını gerektirir. Bu nedenle, sıfır değilse istek kimliğinin belirtilmesi gerekir. Bu, geçerli bir WorkResponse.

{
  "requestId" : 12,
}

0 olan request_id değeri, "singleplex" isteğini belirtir ve bu istek diğer isteklere paralel olarak işlenemediğinde 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 istek almasını garanti eder. Singleplex istekleri seri olarak gönderilir. Örneğin, sunucu bir yanıt alana kadar başka bir istek göndermezse (iptal istekleri hariç olmak üzere aşağıya bakın).

Notes

  • Her protokol arabelleğinin önünde, varint biçiminde uzunluğu bulunur (MessageLite.writeDelimitedTo() bölümüne bakın.
  • JSON isteklerinin ve yanıtlarının öncesinde bir boyut göstergesi bulunmaz.
  • JSON istekleri, protobuf ile aynı yapıyı destekler ancak tüm alan adları için standart JSON ve büyük/küçük harf kullanır.
  • Protobuf ile aynı geriye ve ileri uyumluluk özelliklerini korumak için JSON çalışanlarının bu mesajlardaki bilinmeyen alanları tolere etmesi ve eksik değerler için proto arabellek varsayılanlarını kullanması gerekir.
  • Bazel, istekleri protobuf olarak depolar ve protobuf'un 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 uzaktan yürütme nedeniyle düzenli olarak kesintiye uğradığı dinamik yürütme durumlarında 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ı ayarlanmış bir WorkRequest'dir (ve benzer bir iptal yanıtı, was_cancelled alanı ayarlanmış bir WorkResponse'dir). İptal veya iptal yanıtında olması gereken tek alan, hangi isteğin iptal edileceğini belirten request_id alanıdır. request_id alanı, tek yönlü çalışanlar için 0, Multiplex çalışanlar için daha önce gönderilmiş bir WorkRequest öğesinin 0 olmayan request_id değeri olur. Sunucu, çalışanın yanıtlamış olduğu istekler için iptal isteği gönderebilir. Bu durumda iptal isteği yok sayılmalıdır.

İptal edilmeyen her WorkRequest mesajı, iptal edilmiş olsun veya olmasın tam olarak bir kez yanıtlanmalıdır. Sunucu bir iptal isteği gönderdikten sonra çalışan, request_id ayarlanmış ve was_cancelled alanı true olarak ayarlanmış bir WorkResponse ile yanıt verebilir. Normal WorkResponse gönderme de kabul edilir ancak output ve exit_code alanları yoksayılır.

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

Çalışanı kullanan kuralı oluşturma

Ayrıca, çalışan tarafından gerçekleştirilecek işlemler oluşturan bir kural da oluşturmanız gerekir. Çalışan kullanan bir Starlark kuralı oluşturmak, tıpkı başka bir kural oluşturmak gibidir.

Buna ek olarak, kuralın çalışanın kendisine bir referans içermesi ve ürettiği eylemler için bazı gereksinimler olması gerekir.

Çalışana atıfta bulunma

Çalışanı kullanan kural, çalışanın kendisine referans veren bir alan içermelidir. Bu nedenle, çalışanınızı tanımlamak için \*\_binary kuralının bir örneğini oluşturmanız gerekir. Çalışanınızın adı MyWorker.Java ise ilişkili kural bu olabilir:

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

Bu, çalışan ikili programını ifade eden "çalışan" etiketini oluşturur. Ardından, çalışanı kullanan bir kural tanımlarsınız. Bu kural, çalışan ikili programına başvuruda bulunan bir özelliği tanımlamalıdır.

Derlediğiniz çalışan ikili programı, derlemenin en üst düzeyinde olan "work" adlı bir paketteyse özellik tanımı şu olabilir:

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

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

İşle ilgili işlem gereksinimleri

Çalışanı kullanan kural, çalışanın gerçekleştireceği işlemler oluşturur. Bu işlemlerin birkaç gereksinimi vardır.

  • "Bağımsız değişkenler" alanı. Bu işlem, dizelerin listesini alır. Bu dizelerin sonuncusu hariç tümü başlangıçta çalışana iletilen bağımsız değişkenlerdir. "Bağımsız değişkenler" listesindeki son öğe, bir flag-file (@-öne sahip) bağımsız değişkenidir. Çalışanlar, belirtilen işaret dosyasındaki bağımsız değişkenleri WorkRequest bazında okur. Kuralınız, bu işaret dosyasına çalışan için başlangıç dışı bağımsız değişkenler yazabilir.

  • "supports-workers" : "1", "supports-multiplex-workers" : "1" veya her ikisini içeren bir sözlüğü alan "execution-requirements" (yürütme-gereksinimleri) alanı.

    Çalışanlara gönderilen tüm işlemler için "bağımsız değişkenler" ve "yürütme-gereksinimleri" alanları zorunludur. Ayrıca, JSON çalışanları tarafından yürütülmesi gereken işlemler, yürütme gereksinimleri alanında "requires-worker-protocol" : "json" içermelidir. "requires-worker-protocol" : "proto" de geçerli bir yürütme koşuludur ancak proto çalışanları için zorunlu değildir ancak varsayılan olarak kullanılır.

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

  • İşlem sırasında oluşturulan geçici dosyalar çalışanın dizinine kaydedilmelidir. Bu, korumalı alana almayı etkinleştirir.

Yukarıda açıklanan "çalışan" özelliğine sahip bir kural tanımının yanı sıra girişleri temsil eden "srcs" özelliği, çıkışları temsil eden "output" özelliği ve çalışan başlangıç bağımsız değişkenlerini temsil eden bir "bağımsız değişken" özelliğine ek olarak ctx.actions.run işlevine yapılan çağrı şu şekilde 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 bölümünü inceleyin.

Örnekler

Bazel kod tabanı, entegrasyon testlerimizde kullanılan örnek bir JSON çalışanının yanı sıra Java derleyici çalışanlarını kullanır.

Herhangi bir Java tabanlı aracı doğru geri çağırmayı ileterek bir çalışana dönüştürmek için bu yapıyı kullanabilirsiniz.

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

Dışarıdan katkıda bulunanlar çeşitli dillerde çalışan uygulamaya koydular. Bazel'in kalıcı çalışanlarının Polyglot uygulamalarına göz atın. GitHub'da daha birçok örnek bulabilirsiniz.