Halaman ini menjelaskan pekerja multipleks, cara menulis aturan yang kompatibel dengan multipleks, dan solusi untuk batasan tertentu.
Pekerja multipleks memungkinkan Bazel menangani beberapa permintaan dengan satu proses pekerja. Untuk pekerja multi-thread, Bazel dapat menggunakan lebih sedikit resource untuk mencapai performa yang sama atau lebih baik. Misalnya, daripada memiliki satu proses pekerja per pekerja, Bazel dapat memiliki empat pekerja multipleks yang berkomunikasi dengan proses pekerja yang sama, yang kemudian dapat menangani permintaan secara paralel. Untuk bahasa seperti Java dan Scala, cara ini menghemat waktu pemanasan JVM dan waktu kompilasi JIT, dan secara umum memungkinkan penggunaan satu cache bersama antara semua pekerja dari jenis yang sama.
Ringkasan
Ada dua lapisan antara server Bazel dan proses pekerja. Untuk mnemonik tertentu yang dapat menjalankan proses secara paralel, Bazel akan mendapatkan WorkerProxy
dari kumpulan pekerja. WorkerProxy
meneruskan permintaan ke proses pekerja
secara berurutan bersama dengan request_id
, proses pekerja akan memproses permintaan
dan mengirimkan respons ke WorkerMultiplexer
. Saat
menerima respons, WorkerMultiplexer
akan mengurai request_id
, lalu meneruskan respons tersebut
kembali ke WorkerProxy
yang benar. Sama seperti pekerja non-multiplex, semua
komunikasi dilakukan melalui in/out standar, tetapi alat ini tidak bisa hanya menggunakan
stderr
untuk output yang terlihat oleh pengguna (lihat di bawah).
Setiap pekerja memiliki kunci. Bazel menggunakan kode hash kunci (terdiri dari variabel lingkungan, root eksekusi, dan mnemonic) untuk menentukan WorkerMultiplexer
mana yang akan digunakan. WorkerProxy
berkomunikasi dengan WorkerMultiplexer
yang sama jika memiliki kode hash yang sama. Oleh karena itu, dengan asumsi variabel lingkungan dan root eksekusi sama dalam satu pemanggilan Bazel, setiap mnemonik unik hanya dapat memiliki satu WorkerMultiplexer
dan satu proses pekerja. Jumlah total pekerja, termasuk pekerja reguler dan WorkerProxy
, masih dibatasi oleh --worker_max_instances
.
Menulis aturan yang kompatibel dengan multipleks
Proses pekerja aturan harus multi-thread untuk memanfaatkan
pekerja multipleks. Protobuf memungkinkan kumpulan aturan untuk mengurai satu permintaan meskipun mungkin ada beberapa permintaan yang menumpuk dalam aliran. Setiap kali
proses pekerja mengurai permintaan dari aliran, proses tersebut harus menangani permintaan tersebut di
thread baru. Karena thread yang berbeda dapat menyelesaikan dan menulis ke aliran data secara bersamaan, proses pekerja perlu memastikan bahwa respons ditulis secara atomik (pesan tidak tumpang tindih). Respons harus berisi
request_id
permintaan yang ditangani.
Menangani output multipleks
Pekerja multipleks harus lebih berhati-hati dalam menangani output mereka daripada
pekerja singleton. Apa pun yang dikirim ke stderr
akan masuk ke satu file log
yang dibagikan di antara semua WorkerProxy
dengan jenis yang sama,
yang disisipi secara acak di antara permintaan serentak. Meskipun mengalihkan stdout
ke stderr
adalah ide yang bagus, jangan kumpulkan output tersebut ke kolom output
dari WorkResponse
, karena hal itu dapat menampilkan potongan output yang rusak kepada pengguna.
Jika alat Anda hanya mengirimkan output berorientasi pengguna ke stdout
atau stderr
, Anda harus
mengubah perilaku tersebut sebelum dapat mengaktifkan pekerja multipleks.
Mengaktifkan pekerja multipleks
Pekerja multipleks tidak diaktifkan secara default. Kumpulan aturan dapat mengaktifkan pekerja multipleks dengan menggunakan tag supports-multiplex-workers
di execution_requirements
tindakan (sama seperti tag supports-workers
yang memungkinkan pekerja reguler). Seperti halnya saat menggunakan pekerja reguler, strategi pekerja harus ditentukan, baik di tingkat kumpulan aturan (misalnya, --strategy=[some_mnemonic]=worker
) maupun secara umum di tingkat strategi (misalnya --dynamic_local_strategy=worker,standalone
.) Tidak ada tanda tambahan yang diperlukan, dan supports-multiplex-workers
akan lebih diutamakan daripada supports-workers
jika keduanya ditetapkan. Anda dapat menonaktifkan pekerja multipleks secara global dengan meneruskan --noexperimental_worker_multiplex
.
Kumpulan aturan dianjurkan untuk menggunakan pekerja multipleks jika memungkinkan, untuk mengurangi tekanan memori dan meningkatkan performa. Namun, pekerja multipleks saat ini tidak kompatibel dengan eksekusi dinamis kecuali jika mereka menerapkan sandbox multipleks. Mencoba menjalankan pekerja multipleks yang tidak di-sandbox dengan eksekusi dinamis akan menggunakan pekerja singleton dengan sandbox secara otomatis.
Sandbox multipleks
Pekerja multipleks dapat di-sandbox dengan menambahkan dukungan eksplisit untuknya dalam penerapan pekerja. Meskipun sandbox pekerja singleplex dapat dilakukan dengan menjalankan setiap proses pekerja di sandbox-nya sendiri, pekerja multipleks berbagi direktori kerja proses di antara beberapa permintaan paralel. Untuk mengizinkan sandbox bagi pekerja multipleks, pekerja harus mendukung pembacaan dari dan penulisan ke subdirektori yang ditentukan dalam setiap permintaan, bukan secara langsung di direktori kerjanya.
Untuk mendukung sandbox multipleks, pekerja harus menggunakan kolom sandbox_dir
dari WorkRequest
dan menggunakannya sebagai awalan untuk semua pembacaan dan penulisan file.
Meskipun kolom arguments
dan inputs
tidak berubah dari permintaan yang tidak di-sandbox, input sebenarnya akan relatif terhadap sandbox_dir
. Worker harus
menerjemahkan jalur file yang ditemukan di arguments
dan inputs
untuk membaca dari
jalur yang diubah ini, dan juga harus menulis semua output yang terkait dengan sandbox_dir
.
Ini mencakup jalur seperti '.', serta jalur yang ditemukan dalam file yang ditentukan dalam argumen (seperti argumen "argfile").
Setelah pekerja mendukung sandbox multipleks, kumpulan aturan dapat mendeklarasikan dukungan ini dengan menambahkan supports-multiplex-sandboxing
ke execution_requirements
suatu tindakan. Kemudian, Bazel akan menggunakan sandbox multipleks
jika tanda --experimental_worker_multiplex_sandboxing
diteruskan, atau jika
pekerja digunakan dengan eksekusi dinamis.
File pekerja dari pekerja multipleks dalam sandbox masih relatif terhadap direktori kerja proses pekerja. Jadi, jika file
digunakan untuk menjalankan pekerja dan sebagai input, file tersebut harus ditentukan sebagai
input dalam argumen file flag serta dalam tools
, executable
, atau
runfiles
.