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

Sorun bildirin Kaynağı göster

Kalıcı çalışanlar, derlemenizi hızlandırabilir. Derlemenizde başlangıç maliyeti yüksek olan veya işlemler arası önbelleğe alma işleminden faydalanabilecek 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ı iki bölümden oluşur:

Bir işi yapmak

Israrlı bir çalışan birkaç şartı yerine getirir:

  • stdin öğesinden WorkRequests değerini okur.
  • stdout öğesine 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 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 bir istek kimliği içerir.

NOT: Protokol arabelleği 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ımı, 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. Yüksek değerler, daha ayrıntılı çıktıyı gösterir. --worker_verbose işareti Bazel'a iletildiğinde verbosity alanı 10 olarak ayarlanır. Ancak farklı çıktı 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 karşılık gelen WorkResponse öğelerinin aynı istek kimliğine sahip olmasını gerektirir. Bu nedenle, sıfır olmayan bir istek kimliği belirtilmelidir. Bu geçerli bir WorkResponse.

{
  "requestId" : 12,
}

request_id değerinin 0 olması, bu istek diğer isteklerle paralel olarak işlenemediğinde kullanılan "singleplex" isteğini gösterir. 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 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ğinden önce varint biçimindeki uzunluğu gelir (bkz. MessageLite.writeDelimitedTo()).
  • 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. İptal işlemine 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 değerindeki 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, çalışan, request_id ayarlı ve was_cancelled alanının doğru değerine ayarlandığı 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. Çalışan kullanan bir Starlark kuralı oluşturmak, başka herhangi bir kural oluşturmaya benzer.

Buna ek olarak, kuralın çalışanın kendisine bir referans içermesi gerekir ve çalıştığı eylemler için bazı gereksinimler 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, çalışanı kullanan bir kural tanımlarsınız. Bu kural, çalışan ikili programıyla ilgili bir özellik tanımlamalıdır.

Derlediğiniz çalışan ikili programı, derlemenin en üst düzeyindeki "iş" 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 (ö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şlemler oluşturur. Bu işlemlerin birkaç gereksinimi vardır.

  • "bağımsız değişkenler" alanı. Bu, bir dize listesi alır. Bu dizelerin sonuncusu hariç başlatma sırasında çalışana iletilen bağımsız değişkenlerdir. "Bağımsız değişkenler" listesindeki son öğe, bir flag-file (@ öncesinde sunulan) bağımsız değişkenidir. Çalışanlar, belirtilen işaret dosyasındaki bağımsız değişkenleri WorkRequest başına ayrı olarak okur. Kuralınız, bu işaret dosyasına çalışan için başlatma olmayan 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ı.

    Çalışanlara gönderilen tüm işlemler için "bağımsız değişkenler" ve "yürütme-şartları" alanları zorunludur. Ayrıca, JSON çalışanları tarafından yürütülmesi gereken işlemlerin, yürütme gereksinimleri alanına "requires-worker-protocol" : "json" değerini dahil etmesi 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.

Yapılarını kullanarak doğru geri çağırmayı ileterek Java tabanlı herhangi bir aracı çalışana dönüştürebilirsiniz.

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

Kuruluş dışından katkıda bulunanlar, çalışanları çeşitli dillerde kullanmaya başlamıştır. Kalıcı Bazel çalışanlarının Polyglot uygulamalarına göz atın. GitHub'da daha pek çok örnek bulabilirsiniz.