Membuat Pekerja Tetap

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.
Laporkan masalah Lihat sumber

Pekerja persisten dapat membuat build Anda lebih cepat. Jika Anda memiliki tindakan berulang dalam build yang memiliki biaya startup tinggi atau akan mendapatkan manfaat dari caching lintas tindakan, Anda dapat menerapkan pekerja persistensi Anda sendiri untuk melakukan tindakan ini.

Server Bazel berkomunikasi dengan pekerja menggunakan stdin/stdout. Server ini mendukung penggunaan buffering protokol atau string JSON.

Implementasi pekerja memiliki dua bagian:

Membuat pekerja

Pekerja persisten menegakkan beberapa persyaratan:

  • Kode ini membaca WorkRequests dari stdin-nya.
  • Menulis WorkResponses (dan hanya WorkResponse) ke stdout.
  • Flag tersebut menerima flag --persistent_worker. Wrapper harus mengenali flag command line --persistent_worker dan hanya membuat dirinya tetap jika flag tersebut diteruskan, jika tidak, wrapper harus melakukan kompilasi satu kali dan keluar.

Jika program Anda menegakkan persyaratan ini, program tersebut dapat digunakan sebagai pekerja persisten.

Permintaan pekerjaan

WorkRequest berisi daftar argumen kepada pekerja, daftar pasangan jalur yang mewakili input yang dapat diakses pekerja (ini tidak diterapkan, tetapi Anda dapat menggunakan info ini untuk meng-cache), dan id permintaan, yaitu 0 untuk pekerja singleplex.

CATATAN: Meskipun spesifikasi buffering protokol menggunakan "case case" (request_id), protokol JSON menggunakan "camel case" (requestId). Dokumen ini menggunakan camel case dalam contoh JSON, tetapi kasus ular saat berbicara tentang kolom terlepas dari protokolnya.

{
  "arguments" : ["--some_argument"],
  "inputs" : [
    { "path": "/path/to/my/file/1", "digest": "fdk3e2ml23d"},
    { "path": "/path/to/my/file/2", "digest": "1fwqd4qdd" }
 ],
  "requestId" : 12
}

Kolom verbosity opsional dapat digunakan untuk meminta output proses debug tambahan dari pekerja. Semuanya bergantung sepenuhnya pada pekerja dan cara outputnya. Nilai yang lebih tinggi menunjukkan output yang lebih panjang. Meneruskan tanda --worker_verbose ke Bazel akan menetapkan kolom verbosity ke 10, tetapi nilai yang lebih kecil atau lebih besar dapat digunakan secara manual untuk jumlah output yang berbeda.

Kolom sandbox_dir opsional hanya digunakan oleh pekerja yang mendukung sandbox multipleks.

Respons kerja

WorkResponse berisi ID permintaan, kode keluar nol atau bukan nol, dan string output yang menjelaskan setiap error yang terjadi dalam pemrosesan atau eksekusi permintaan. Kolom output berisi deskripsi singkat; log lengkap dapat ditulis ke stderr pekerja. Karena pekerja hanya dapat menulis WorkResponses ke stdout, yang umum bagi pekerja untuk mengalihkan stdout dari alat apa pun yang digunakannya ke stderr.

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

Sesuai standar untuk protobuf, semua kolom bersifat opsional. Namun, Bazel memerlukan WorkRequest dan WorkResponse yang sesuai, agar memiliki ID permintaan yang sama, sehingga ID permintaan harus ditentukan jika bukan nol. Ini adalah WorkResponse yang valid.

{
  "requestId" : 12,
}

request_id 0 menunjukkan permintaan "singleplex", yang digunakan saat permintaan ini tidak dapat diproses secara paralel dengan permintaan lain. Server menjamin bahwa pekerja tertentu menerima permintaan hanya dengan request_id 0 atau hanya request_id yang lebih besar dari nol. Permintaan singleplex dikirim dalam bentuk serial, misalnya jika server tidak mengirimkan permintaan lain hingga menerima respons (kecuali untuk permintaan pembatalan, lihat di bawah).

Catatan

  • Setiap buffering protokol didahului oleh panjangnya dalam format varint (lihat MessageLite.writeDelimitedTo().
  • Respons dan permintaan JSON tidak didahului dengan indikator ukuran.
  • Permintaan JSON memiliki struktur yang sama dengan protobuf, tetapi menggunakan JSON standar dan menggunakan camel case untuk semua nama kolom.
  • Untuk mempertahankan properti kompatibilitas mundur dan maju yang sama seperti protobuf, pekerja JSON harus menoleransi kolom yang tidak dikenal dalam pesan ini, dan menggunakan default protobuf untuk nilai yang tidak ada.
  • Bazel menyimpan permintaan sebagai protobuf dan mengonversinya menjadi JSON menggunakan format JSON protobuf

Peredam Bising

Pekerja dapat secara opsional mengizinkan permintaan pekerjaan dibatalkan sebelum selesai. Hal ini sangat berguna sehubungan dengan eksekusi dinamis, karena eksekusi lokal dapat sering terganggu oleh eksekusi jarak jauh yang lebih cepat. Untuk mengizinkan pembatalan, tambahkan supports-worker-cancellation: 1 ke kolom execution-requirements (lihat di bawah) dan tetapkan tanda --experimental_worker_cancellation.

Permintaan pembatalan adalah WorkRequest dengan kolom cancel yang ditetapkan (dan sama seperti batalkan respons adalah WorkResponse dengan kumpulan kolom was_cancelled). Satu-satunya kolom lain yang harus ada dalam permintaan pembatalan atau respons pembatalan adalah request_id, yang menunjukkan permintaan mana yang akan dibatalkan. Kolom request_id akan bernilai 0 untuk pekerja singleplex atau request_id non-0 dari WorkRequest yang sebelumnya dikirim untuk pekerja multipleks. Server dapat mengirim permintaan pembatalan untuk permintaan yang telah direspons oleh pekerja, dalam hal ini permintaan pembatalan harus diabaikan.

Setiap pesan WorkRequest yang tidak dibatalkan harus dijawab tepat satu kali, baik dibatalkan maupun tidak. Setelah server mengirim permintaan pembatalan, pekerja dapat merespons dengan WorkResponse yang menetapkan request_id dan kolom was_cancelled yang ditetapkan ke true. Mengirim WorkResponse reguler juga diterima, tetapi kolom output dan exit_code akan diabaikan.

Setelah respons dikirim untuk WorkRequest, pekerja tidak boleh menyentuh file dalam direktori kerjanya. Server bebas membersihkan file, termasuk file sementara.

Membuat aturan yang menggunakan pekerja

Anda juga perlu membuat aturan yang menghasilkan tindakan yang akan dilakukan oleh pekerja. Membuat aturan Starlark yang menggunakan pekerja sama seperti membuat aturan lain.

Selain itu, aturan harus berisi referensi ke pekerja itu sendiri, dan ada beberapa persyaratan untuk tindakan yang dihasilkannya.

Merujuk ke pekerja

Aturan yang menggunakan pekerja harus berisi kolom yang merujuk ke pekerja itu sendiri, sehingga Anda harus membuat instance aturan \*\_binary untuk menentukan pekerja. Jika pekerja Anda disebut MyWorker.Java, ini mungkin aturan terkait:

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

Tindakan ini akan membuat label "pekerja", yang mengacu pada biner pekerja. Kemudian, tentukan aturan yang menggunakan pekerja. Aturan ini harus menentukan atribut yang merujuk ke biner pekerja.

Jika biner pekerja yang Anda build berada dalam paket bernama "work", yang berada di tingkat teratas build, ini mungkin merupakan definisi atribut:

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

cfg = "exec" menunjukkan bahwa pekerja harus di-build untuk berjalan di platform eksekusi, bukan di platform target (misalnya, pekerja digunakan sebagai alat selama proses build).

Persyaratan tindakan kerja

Aturan yang menggunakan pekerja membuat tindakan untuk dilakukan pekerja. Tindakan ini memiliki beberapa persyaratan.

  • Kolom "argumen". Ini mengambil daftar string, semua string kecuali yang terakhir adalah argumen yang diteruskan ke pekerja saat memulai. Elemen terakhir dalam daftar "argumen" adalah argumen flag-file (@-preceded). Pekerja membaca argumen dari flagfile yang ditentukan berdasarkan per-WorkRequest. Aturan Anda dapat menulis argumen non-startup untuk pekerja ke filefile ini.

  • Kolom "Execution-requirements", yang menggunakan kamus yang berisi "supports-workers" : "1", "supports-multiplex-workers" : "1", atau keduanya.

    Kolom "argumen" dan "persyaratan eksekusi" diperlukan untuk semua tindakan yang dikirim ke pekerja. Selain itu, tindakan yang harus dijalankan oleh pekerja JSON harus menyertakan "requires-worker-protocol" : "json" di kolom persyaratan eksekusi. "requires-worker-protocol" : "proto" juga merupakan persyaratan eksekusi yang valid, meskipun tidak diperlukan untuk pekerja proto, karena mereka merupakan nilai default.

    Anda juga dapat menetapkan worker-key-mnemonic dalam persyaratan eksekusi. Hal ini mungkin berguna jika Anda menggunakan kembali file yang dapat dieksekusi untuk beberapa jenis tindakan dan ingin membedakan tindakan menurut pekerja ini.

  • File sementara yang dihasilkan dalam tindakan harus disimpan ke direktori pekerja. Tindakan ini akan mengaktifkan sandbox.

Dengan asumsi definisi aturan dengan atribut "pekerja" yang dijelaskan di atas, selain atribut "src" yang mewakili input, atribut "output" yang mewakili output, dan atribut "args" yang mewakili argumen startup pekerja, panggilan ke ctx.actions.run mungkin:

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"]
 )

Untuk contoh lainnya, lihat Mengimplementasikan pekerja persisten.

Contoh

Basis kode Bazel menggunakan pekerja compiler Java, selain contoh pekerja JSON yang digunakan dalam pengujian integrasi kami.

Anda dapat menggunakan scaffolding mereka untuk membuat alat berbasis Java menjadi pekerja dengan meneruskan callback yang benar.

Untuk contoh aturan yang menggunakan pekerja, lihat pengujian integrasi pekerja Bazel.

Kontributor eksternal telah menerapkan pekerja dalam berbagai bahasa; lihat Penerapan Polyglot dari pekerja persisten Bazel. Anda dapat menemukan banyak contoh lainnya di GitHub.