Halaman ini menjelaskan pekerja multipleks, cara menulis yang kompatibel dengan multipleks aturan, dan solusi untuk batasan tertentu.
Pekerja multipleks memungkinkan Bazel menangani beberapa permintaan dengan satu pekerja {i>checkout<i}. Untuk pekerja multi-thread, Bazel dapat menggunakan lebih sedikit resource untuk mencapai performa yang sama atau lebih baik. Misalnya, alih-alih memiliki satu setiap pekerja, Bazel dapat memiliki empat pekerja multipleks yang dapat berbicara proses pekerja yang sama, yang kemudian dapat menangani permintaan secara paralel. Sebagai bahasa seperti Java dan Scala, ini menghemat waktu pemanasan JVM dan kompilasi JIT dan umumnya memungkinkan penggunaan satu {i>cache<i} bersama di antara semua pekerja jenis yang sama.
Ringkasan
Ada dua lapisan antara server Bazel dan proses pekerja. Untuk tertentu
yang dapat menjalankan proses secara paralel, Bazel mendapatkan WorkerProxy
dari
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 WorkerMultiplexer
menerima respons, kode ini akan mengurai request_id
lalu meneruskan respons
kembali ke WorkerProxy
yang benar. Sama seperti pekerja non-multiplex, semua
komunikasi dilakukan secara {i>standard in/out<i},
tetapi alat ini tidak bisa hanya menggunakan
stderr
untuk output yang terlihat oleh pengguna (lihat di bawah).
Setiap pekerja memiliki kunci. Bazel menggunakan kode {i>hash<i} kunci (terdiri dari lingkungan
variabel, eksekusi root, dan mnemonik) untuk menentukan
WorkerMultiplexer
untuk digunakan. WorkerProxy
berkomunikasi dengan
WorkerMultiplexer
jika keduanya memiliki kode hash yang sama. Oleh karena itu, dengan asumsi
variabel lingkungan dan root eksekusi
yang sama dalam satu Bazel
pemanggilan, 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, bahkan
meskipun mungkin ada beberapa permintaan
yang menumpuk di aliran. Kapan pun
proses pekerja mengurai permintaan dari aliran, ia harus menangani permintaan dalam
utas baru. Karena utas yang berbeda dapat menyelesaikan
dan menulis ke aliran data pada
pada saat yang sama, proses pekerja perlu
memastikan respon ditulis
secara atomik (pesan tidak tumpang tindih). Respons harus berisi
request_id
dari permintaan yang ditangani.
Menangani output multipleks
Pekerja multipleks harus lebih berhati-hati dalam menangani output mereka daripada
pekerja singleplex. Apa pun yang dikirim ke stderr
akan masuk ke satu file log
dibagikan di antara semua WorkerProxy
dengan jenis yang sama,
diselang-seling secara acak di
antara permintaan-permintaan serentak. Saat mengalihkan stdout
ke dalam stderr
adalah ide yang bagus, jangan mengumpulkan output tersebut ke dalam output
WorkResponse
, karena hal tersebut dapat menunjukkan output yang rusak kepada pengguna.
Jika alat Anda hanya mengirimkan output berorientasi pengguna ke stdout
atau stderr
, Anda akan
perlu mengubah perilaku tersebut sebelum Anda dapat mengaktifkan pekerja multipleks.
Mengaktifkan pekerja multipleks
Pekerja multipleks tidak diaktifkan secara default. Sekumpulan aturan dapat mengaktifkan multipleks
pekerja dengan menggunakan tag supports-multiplex-workers
di
execution_requirements
tindakan (sama seperti tag supports-workers
memungkinkan pekerja reguler). Seperti halnya ketika menggunakan pekerja reguler, pekerja
menentukan strategi, baik di tingkat kumpulan aturan (misalnya,
--strategy=[some_mnemonic]=worker
) atau umumnya di tingkat strategi (untuk
misalnya, --dynamic_local_strategy=worker,standalone
.) Tidak ada flag tambahan yang
diperlukan, dan supports-multiplex-workers
lebih diprioritaskan daripada
supports-workers
, jika keduanya sudah ditetapkan. Anda dapat menonaktifkan pekerja multipleks
secara global dengan meneruskan --noworker_multiplex
.
Kumpulan aturan dianjurkan untuk menggunakan pekerja multipleks jika memungkinkan, untuk mengurangi memori tekanan dan meningkatkan kinerja. Namun, saat ini pekerja multipleks kompatibel dengan eksekusi dinamis kecuali jika menerapkan sandbox multipleks. Mencoba menjalankan multipleks tanpa sandbox pekerja dengan eksekusi dinamis akan menggunakan sandbox secara otomatis pekerja singleplex.
Sandbox multipleks
Pekerja multipleks dapat di-sandbox dengan menambahkan dukungan eksplisit untuknya di implementasi pekerja. Meskipun sandbox pekerja singleplex dapat dilakukan dengan yang menjalankan setiap proses pekerja di {i>sandbox<i}-nya sendiri, pekerja multipleks berbagi memproses direktori kerja di antara beberapa permintaan paralel. Untuk mengizinkan sandboxing pekerja multipleks, pekerja harus mendukung pembacaan dari dan menulis ke subdirektori yang ditentukan dalam setiap permintaan, alih-alih 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
tetap tidak berubah dari kotak yang tidak di-sandbox
input aktual akan relatif terhadap sandbox_dir
. Pekerja harus
terjemahkan jalur file yang ditemukan di arguments
dan inputs
untuk dibaca dari ini
jalur yang dimodifikasi, dan juga harus menulis semua output yang terkait dengan sandbox_dir
.
Ini termasuk jalur seperti '.', serta jalur yang ditemukan di file yang ditentukan
dalam argumen (seperti argumen "argfile").
Setelah pekerja mendukung sandbox multipleks, kumpulan aturan dapat mendeklarasikan
dengan menambahkan supports-multiplex-sandboxing
ke
execution_requirements
dari suatu tindakan. Bazel kemudian akan menggunakan sandbox multipleks
jika flag --experimental_worker_multiplex_sandboxing
diteruskan, atau jika
worker akan digunakan dengan eksekusi dinamis.
File pekerja dari pekerja multipleks dengan sandbox masih relatif terhadap
direktori kerja proses pekerja. Jadi, jika sebuah file
digunakan untuk menjalankan worker maupun sebagai input, harus ditentukan sebagai
input dalam argumen flagfile serta di tools
, executable
, atau
runfiles
.