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, çalışanla stdin
/stdout
kullanarak iletişim kurar. Protokol arabelleklerinin veya JSON dizelerinin kullanımını destekler.
İşçi uygulaması iki bölümden oluşur:
Çalışanı oluşturma
Israrlı bir çalışan birkaç şartı yerine getirir:
stdin
öğesinden WorkRequests değerini okur.stdout
parametresine 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 bir derleme yapıp çıkmalıdır.
Programınız bu koşulları karşılıyorsa kalıcı bir çalışan olarak kullanılabilir.
İş istekleri
WorkRequest
, çalışana yönelik bir bağımsız değişken listesi, çalışanın erişebileceği girişleri temsil eden yol özeti çiftlerinin bir listesi (bu zorunlu değildir ancak önbelleğe alma için bu bilgiyi kullanabilirsiniz) ve singleplex çalışanları için 0 olan istek kimliğini içerir.
NOT: Protokol arabellek spesifikasyonu "yılan büyük/küçük harf" (request_id
) kullanırken, JSON protokolünde "deve büyük/küçük harf" (requestId
) kullanılır. Bu dokümanda, JSON örneklerinde büyük/küçük harf kullanılır. Ancak protokolden bağımsız olarak alan hakkında konuşurken yılan şeklinde büyük harf 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. Neyin nasıl üretileceği tamamen çalışanın işidir. 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 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ülürken karşılaşılan hataları açıklayan bir çıkış dizesi içerir. output
alanında kısa bir açıklama bulunur. Günlükler, çalışanın stderr
öğesine yazılabilir. Çalışanlar yalnızca stdout
öğesine WorkResponses
yazabileceğinden, kullandığı tüm araçların stdout
öğesini 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
}
Protobuflar standardına göre, 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. Singleplex istekler seri olarak gönderilir. Örneğin, sunucu bir yanıt alana kadar başka bir istek göndermezse (iptal istekleri hariç aşağıdaki bilgilere 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 bulunmaz.
- JSON istekleri, protobuf ile aynı yapıyı korur 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 alanlara izin vermesi ve eksik değerler için protobuf 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 işlemi ile düzenli olarak kesintiye uğratabildiği dinamik yürütmede 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 ayarlanmış olduğu bir WorkRequest
'dir (benzer şekilde, iptal yanıtı da was_cancelled
alanı ayarlanmış bir WorkResponse
olur). İptal isteğinde veya iptal yanıtında olması gereken diğer 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 veya daha önce gönderilmiş WorkRequest
olan Multiplex çalışanları için 0 olmayan request_id
olacaktır. Sunucu, çalışanın daha önce yanıtladığı istekler için iptal istekleri gönderebilir. Bu durumda, iptal isteğinin yoksayılması gerekir.
İptal edilmemiş 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.
WorkRequest
için yanıt gönderildikten sonra, çalışan, çalışma dizinindeki dosyalara dokunmamalıdır. Sunucu, geçici dosyalar da dahil olmak üzere
dosyaları temizleyebilir.
Çalışanı kullanan kuralı yapmak
Ayrıca, çalışan tarafından gerçekleştirilecek işlemler 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 referans verme
Çalışanı kullanan kuralın, çalışanın kendisini ifade eden bir alan içermesi gerekir. 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 şu olabilir:
java_binary(
name = "worker",
srcs = ["MyWorker.Java"],
)
Bu işlem, çalışan ikili programını ifade eden "çalışan" etiketini oluşturur. Ardından, işçiyi kullanan bir kural tanımlarsınız. Bu kural, çalışan ikili programıyla ilgili 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ı şu şekilde 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 (ör. çalışan, derleme sırasında araç olarak kullanılır).
İş eylemi gereksinimleri
Ç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, sonuncusu hariç tümü başlatıldığında işçiye iletilen bağımsız değişkenler olan bir dize listesi alır. "arguments" listesindeki son öğe,
flag-file
(@ işareti ile başlayan) bağımsız değişkenidir. Çalışanlar, WorkRequest başına belirtilen işaret dosyasından bağımsız olarak bağımsız değişkenleri okur. Kuralınız, bu işaret dosyasına çalışan için başlatma dışı bağımsız değişkenler yazabilir."supports-workers" : "1"
,"supports-multiplex-workers" : "1"
veya her ikisini de içeren bir sözlüğü 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"
aynı zamanda geçerli bir yürütme şartıdır ancak varsayılan olarak proto çalışanları için gerekli değildir.Yürütme şartlarında da bir
worker-key-mnemonic
ayarlayabilirsiniz. Yürütülebilir dosyayı birden fazla işlem türü için yeniden kullanıyorsanız ve bu çalışanın işlemlerini ayırt etmek istiyorsanız bu özellik yararlı olabilir.İşlem sırasında oluşturulan geçici dosyalar, çalışanın dizinine kaydedilmelidir. Bu işlem, korumalı alana almayı etkinleştirir.
Yukarıda açıklanan "çalışan" özelliğine sahip bir kural tanımı olduğu varsayıldığında, girişleri temsil eden "srcs" özelliğine, çıkışları temsil eden bir "çıkış" özelliğine 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
ç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 konusuna bakın.
Örnekler
Bazel kod tabanı, entegrasyon testlerimizde kullanılan örnek JSON çalışanına ek olarak Java derleyici çalışanlarını kullanır.
Doğru geri çağırma işlevini göndererek Java tabanlı herhangi bir aracı işçiye dönüştürmek için bu iskeleti 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 pek çok örnek bulabilirsiniz.