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ızcaWorkResponse
) 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.