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

Sorun bildir Kaynağı görüntüle Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Kalıcı çalışanlar, derlemenizi hızlandırabilir. Derlemenizde yüksek başlangıç maliyeti olan veya işlemler arası önbelleğe almadan yararlanacak tekrarlanan işlemler varsa bu işlemleri gerçekleştirmek için kendi kalıcı çalışanınızı uygulayabilirsiniz.

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

Çalışan uygulaması iki bölümden oluşur:

İşçiyi yapma

Kalıcı bir çalışan, birkaç koşulu karşılamalıdır:

  • stdin konumundaki WorkRequests dosyasını okur.
  • stdout konumuna 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 iletilirse kalıcı olmalıdır. Aksi takdirde tek seferlik derleme yapıp çıkmalıdır.

Programınız bu koşulları karşılıyorsa kalıcı çalışan olarak kullanılabilir.

İş istekleri

WorkRequest, çalışana iletilecek bağımsız değişkenlerin listesini, çalışanın erişebileceği girişleri temsil eden yol-özet çiftlerinin listesini (bu zorunlu değildir ancak bu bilgileri önbelleğe alma için kullanabilirsiniz) ve tek kanallı çalışanlar için 0 olan bir istek kimliğini içerir.

NOT: Protokol arabelleği spesifikasyonu "snake case" (request_id) kullanırken JSON protokolü "camel case" (requestId) kullanır. Bu belgedeki JSON örneklerinde camel case kullanılır ancak protokolden bağımsız olarak alandan bahsederken snake case 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. Çalışan, neyi ve nasıl çıktı vereceğine tamamen kendisi karar verir. Değerlerin yüksek olması, daha ayrıntılı bir çıkış olduğunu gösterir. --worker_verbose işaretini Bazel'e iletmek verbosity alanını 10 olarak ayarlar ancak farklı miktarlarda çıkış için daha küçük veya daha büyük değerler manuel olarak kullanılabilir.

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

İşle ilgili yanıtlar

WorkResponse, istek kimliği, sıfır veya sıfır olmayan bir çıkış kodu ve isteğin işlenmesi ya da yürütülmesi sırasında karşılaşılan hataları açıklayan bir çıkış mesajı içerir. Bir çalışan, çağırdığı tüm araçların stdout ve stderr değerlerini yakalamalı ve bunları WorkResponse aracılığıyla bildirmelidir. İşçi protokolüne müdahale edeceğinden, işçi sürecinin stdout yazılması güvenli değildir. Çalışan sürecinin stderr bölümüne yazmak güvenlidir ancak sonuç, bağımsız işlemlere atfedilmek 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 kurala göre tüm alanlar isteğe bağlıdır. Ancak Bazel, WorkRequest ve karşılık gelen WorkResponse değerlerinin aynı istek kimliğine sahip olmasını gerektirir. Bu nedenle, istek kimliği sıfır değilse belirtilmelidir. Bu geçerli bir WorkResponse.

{
  "requestId" : 12,
}

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

Notlar

  • Her protokol arabelleğinden önce varint biçiminde uzunluğu gelir (bkz. MessageLite.writeDelimitedTo()).
  • JSON istekleri ve yanıtlarının başında boyut göstergesi bulunmaz.
  • JSON istekleri, protobuf ile aynı yapıyı korur ancak standart JSON kullanır ve tüm alan adları için camel case kullanılır.
  • JSON çalışanlarının, protobuf ile aynı geriye ve ileriye dönük uyumluluk özelliklerini korumak için 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'un JSON biçimini kullanarak JSON'a dönüştürür.

İptal

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

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

İptal edilmeyen her WorkRequest mesaj, iptal edilmiş olsun veya olmasın tam olarak bir kez yanıtlanmalıdır. Sunucu iptal isteği gönderdikten sonra çalışan, WorkResponse ile yanıt verebilir. Bu yanıtta request_id ayarlanmış ve was_cancelled alanı doğru olarak ayarlanmıştır. 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ı oluşturma

Ayrıca, çalışanın gerçekleştireceği işlemleri oluşturan bir kural da oluşturmanız gerekir. Çalışan kullanan bir Starlark kuralı oluşturmak, diğer kuralları oluşturmaya benzer.

Ayrıca kural, çalışanın kendisine bir referans içermeli ve oluşturduğu işlemlerle ilgili bazı koşullar olmalıdır.

Çalışandan bahsetme

Çalışanı kullanan kural, çalışanın kendisine atıfta bulunan 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 şu olabilir:

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

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

Oluşturduğunuz worker ikilisi, derlemenin en üst düzeyinde bulunan "work" adlı bir paketteyse bu, özellik tanımı olabilir:

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

cfg = "exec", çalışanın hedef platformda değil, yürütme platformunuzda çalışacak şekilde oluşturulması gerektiğini gösterir (ör. çalışan, derleme sırasında araç olarak kullanılır).

Çalışma eylemi şartları

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

  • "arguments" alanı. Bu işlev, dizelerden oluşan bir liste alır. Bu listedeki son dize hariç tüm dizeler, başlangıçta çalışana iletilen bağımsız değişkenlerdir. "arguments" listesindeki son öğe, flag-file (@ ile başlayan) bağımsız değişkenidir. Çalışanlar, belirtilen flagfile'daki bağımsız değişkenleri WorkRequest başına okur. Kuralınız, bu flagfile için çalışana başlangıç dışı argümanlar yazabilir.

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

    Çalışanlara gönderilen tüm işlemler için "arguments" (argümanlar) ve "execution-requirements" (yürütme koşulları) alanları gereklidir. Ayrıca, JSON çalışanları tarafından yürütülmesi gereken işlemler, yürütme koşulları alanında "requires-worker-protocol" : "json" içermelidir. "requires-worker-protocol" : "proto", varsayılan olarak ayarlandığı için proto çalışanları için gerekli olmasa da geçerli bir yürütme koşuludur.

    Yürütme koşullarında worker-key-mnemonic da belirleyebilirsiniz. Bu, yürütülebilir dosyayı birden fazla işlem türü için yeniden kullanıyorsanız ve işlemleri bu çalışan tarafından ayırt etmek istiyorsanız yararlı olabilir.

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

Yukarıda açıklanan "worker" özelliğine sahip bir kural tanımının yanı sıra girişleri temsil eden bir "srcs" özelliği, çıkışları temsil eden bir "output" özelliği ve worker başlatma bağımsız değişkenlerini temsil eden bir "args" özelliği olduğunu varsayarsak ctx.actions.run çağrısı ş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 başlıklı makaleyi inceleyin.

Örnekler

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

Doğru geri çağırma işlevini ileterek Java tabanlı tüm araçları worker'a dönüştürmek için bu araçların iskelelerini kullanabilirsiniz.

Çalışan kullanan bir kural örneği için Bazel'in worker integration test (Çalışan entegrasyon testi) bölümüne bakın.

Harici katkıda bulunanlar, çeşitli dillerde çalışanlar uygulamıştır. Bazel kalıcı çalışanlarının çok dilli uygulamalarına göz atın. GitHub'da çok daha fazla örnek bulabilirsiniz.