Halaman ini menjelaskan pekerja multiplex, cara menulis aturan yang kompatibel dengan multiplex, dan solusi untuk batasan tertentu.
Multiplex worker memungkinkan Bazel menangani beberapa permintaan dengan satu proses worker. Untuk pekerja multi-thread, Bazel dapat menggunakan lebih sedikit resource untuk mencapai performa yang sama atau lebih baik. Misalnya, alih-alih memiliki satu proses pekerja per pekerja, Bazel dapat memiliki empat pekerja yang di-multiplexing yang berkomunikasi dengan proses pekerja yang sama, yang kemudian dapat menangani permintaan secara paralel. Untuk bahasa seperti Java dan Scala, hal ini menghemat waktu pemanasan JVM dan waktu kompilasi JIT, dan secara umum memungkinkan penggunaan satu cache bersama di antara semua pekerja dengan jenis yang sama.
Ringkasan
Ada dua lapisan antara server Bazel dan proses pekerja. Untuk mnemonik tertentu yang dapat menjalankan proses secara paralel, Bazel mendapatkan WorkerProxy
dari kumpulan pekerja. WorkerProxy
meneruskan permintaan ke proses pekerja secara berurutan bersama dengan request_id
, proses pekerja memproses permintaan dan mengirimkan respons ke WorkerMultiplexer
. Saat WorkerMultiplexer
menerima respons, WorkerMultiplexer
akan mengurai request_id
, lalu meneruskan respons
kembali ke WorkerProxy
yang benar. Sama seperti pekerja non-multiplex, semua
komunikasi dilakukan melalui input/output standar, tetapi alat tidak dapat hanya menggunakan
stderr
untuk output yang terlihat pengguna (lihat di bawah).
Setiap pekerja memiliki kunci. Bazel menggunakan kode hash kunci (yang terdiri dari variabel
lingkungan, root eksekusi, dan mnemonik) untuk menentukan
WorkerMultiplexer
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 multiplex
Proses pekerja aturan harus multi-thread untuk memanfaatkan pekerja multiplex. Protobuf memungkinkan ruleset mengurai satu permintaan meskipun mungkin ada beberapa permintaan yang menumpuk di stream. Setiap kali
proses pekerja mengurai permintaan dari stream, proses tersebut harus menangani permintaan di
thread baru. Karena thread yang berbeda dapat menyelesaikan dan menulis ke stream secara bersamaan, proses pekerja harus memastikan respons ditulis secara atomik (pesan tidak tumpang-tindih). Respons harus berisi
request_id
permintaan yang ditanganinya.
Menangani output multipleks
Pekerja multiproses perlu lebih berhati-hati dalam menangani output mereka daripada pekerja proses tunggal. Apa pun yang dikirim ke stderr
akan masuk ke satu file log yang dibagikan di antara semua WorkerProxy
dengan jenis yang sama, yang disisipkan 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 output yang rusak kepada pengguna.
Jika alat Anda hanya mengirim output yang berorientasi pada pengguna ke stdout
atau stderr
, Anda harus mengubah perilaku tersebut sebelum dapat mengaktifkan pekerja multiplex.
Mengaktifkan pekerja multiplex
Pekerja multipleks tidak diaktifkan secara default. Kumpulan aturan dapat mengaktifkan pekerja multiplex
dengan menggunakan tag supports-multiplex-workers
di
execution_requirements
tindakan (seperti tag supports-workers
mengaktifkan pekerja reguler). Seperti halnya saat menggunakan pekerja biasa, strategi pekerja perlu ditentukan, baik di tingkat ruleset (misalnya, --strategy=[some_mnemonic]=worker
) atau secara umum di tingkat strategi (misalnya, --dynamic_local_strategy=worker,standalone
). Tidak ada flag tambahan yang diperlukan, dan supports-multiplex-workers
lebih diutamakan daripada supports-workers
, jika keduanya ditetapkan. Anda dapat menonaktifkan pekerja multiplex
secara global dengan meneruskan --noworker_multiplex
.
Set aturan dianjurkan untuk menggunakan pekerja multiplex jika memungkinkan, untuk mengurangi tekanan memori dan meningkatkan performa. Namun, pekerja multiplex saat ini tidak kompatibel dengan eksekusi dinamis kecuali jika mereka menerapkan sandbox multiplex. Mencoba menjalankan pekerja multiplex non-sandbox dengan eksekusi dinamis akan menggunakan pekerja singleplex sandbox secara diam-diam.
Sandbox multipleks
Pekerja multiplex dapat di-sandbox dengan menambahkan dukungan eksplisit untuknya dalam implementasi pekerja. Meskipun sandboxing worker simpleks dapat dilakukan dengan menjalankan setiap proses worker di sandbox-nya sendiri, worker multipleks berbagi direktori kerja proses di antara beberapa permintaan paralel. Untuk mengizinkan sandbox pekerja multiplex, pekerja harus mendukung pembacaan dari dan penulisan ke subdirektori yang ditentukan di setiap permintaan, bukan langsung di direktori kerjanya.
Untuk mendukung sandbox multiplex, pekerja harus menggunakan kolom sandbox_dir
dari WorkRequest
dan menggunakannya sebagai awalan untuk semua pembacaan dan penulisan file.
Meskipun kolom arguments
dan inputs
tetap tidak berubah dari permintaan yang tidak di-sandbox, input sebenarnya relatif terhadap sandbox_dir
. Pekerja harus menerjemahkan jalur file yang ditemukan di arguments
dan inputs
untuk dibaca dari jalur yang diubah ini, dan juga harus menulis semua output relatif terhadap sandbox_dir
.
Hal ini mencakup jalur seperti '.', serta jalur yang ditemukan dalam file yang ditentukan dalam argumen (seperti argumen "argfile").
Setelah pekerja mendukung sandbox multiplex, ruleset dapat mendeklarasikan dukungan ini dengan menambahkan supports-multiplex-sandboxing
ke
execution_requirements
tindakan. Bazel kemudian akan menggunakan sandbox multiplex
jika flag --experimental_worker_multiplex_sandboxing
diteruskan, atau jika
pekerja digunakan dengan eksekusi dinamis.
File pekerja dari pekerja multiplex yang di-sandbox masih relatif terhadap
direktori kerja proses pekerja. Oleh karena itu, jika file digunakan
untuk menjalankan pekerja dan sebagai input, file tersebut harus ditentukan sebagai
input dalam argumen flagfile serta dalam tools
, executable
, atau
runfiles
.