Trang này mô tả các worker đa năng, cách viết quy tắc tương thích với nhiều luồng và giải pháp cho một số hạn chế nhất định.
Trình chạy nhiều luồng cho phép Bazel xử lý nhiều yêu cầu bằng một quy trình trình chạy duy nhất. Đối với các worker đa luồng, Bazel có thể sử dụng ít tài nguyên hơn để đạt được hiệu suất tương tự hoặc tốt hơn. Ví dụ: thay vì có một quy trình worker cho mỗi worker, Bazel có thể có 4 worker được đa kênh hoá giao tiếp với cùng một quy trình worker, sau đó có thể xử lý các yêu cầu song song. Cho như Java và Scala, phương án này sẽ giúp tiết kiệm thời gian khởi động JVM và biên dịch JIT thời gian và nói chung, API này cho phép sử dụng một bộ nhớ đệm dùng chung giữa tất cả các worker cùng loại.
Tổng quan
Có 2 lớp giữa máy chủ Bazel và quy trình worker. Đối với một số ký hiệu mnemonics nhất định có thể chạy các quy trình song song, Bazel sẽ nhận được WorkerProxy
từ nhóm worker. WorkerProxy
chuyển tiếp các yêu cầu đến quy trình worker theo tuần tự cùng với request_id
, quy trình worker xử lý yêu cầu và gửi phản hồi đến WorkerMultiplexer
. Khi WorkerMultiplexer
nhận được phản hồi, trình phân tích cú pháp request_id
sẽ phân tích cú pháp rồi chuyển tiếp phản hồi
quay lại đúng WorkerProxy
. Cũng giống như với những nhân viên không làm việc theo kênh đa kênh, tất cả
giao tiếp được thực hiện qua phương thức nhập/xuất chuẩn, nhưng công cụ không thể chỉ sử dụng
stderr
cho đầu ra mà người dùng có thể nhìn thấy (xem bên dưới).
Mỗi worker có một khoá. Bazel sử dụng mã băm của khoá (bao gồm các biến môi trường, thư mục gốc thực thi và câu thần chú) để xác định WorkerMultiplexer
cần sử dụng. Các WorkerProxy
sẽ giao tiếp với cùng một WorkerMultiplexer
nếu chúng có cùng một mã băm. Do đó, giả sử
biến môi trường và gốc thực thi đều giống nhau trong một Bazel
lệnh gọi, mỗi ghi nhớ duy nhất chỉ có thể có một WorkerMultiplexer
và một
của trình thực thi. Tổng số worker, bao gồm cả worker thông thường và WorkerProxy
, vẫn bị giới hạn bởi --worker_max_instances
.
Viết quy tắc tương thích với nhiều kênh
Quy trình thực thi của quy tắc phải là đa luồng để tận dụng
nhiều trình thực thi. Protobuf cho phép một quy tắc phân tích cú pháp một yêu cầu duy nhất mặc dù có thể có nhiều yêu cầu đang xếp chồng trong luồng. Bất cứ khi nào quy trình worker phân tích cú pháp một yêu cầu từ luồng, quy trình đó sẽ xử lý yêu cầu trong một luồng mới. Do các chuỗi khác nhau có thể hoàn tất và ghi vào luồng tại
đồng thời, quy trình của worker cần đảm bảo phản hồi được viết
theo từng tỷ lệ (thư không chồng chéo nhau). Phản hồi phải chứa request_id
của yêu cầu mà chúng đang xử lý.
Xử lý đầu ra đa kênh
Worker multiplex cần cẩn thận hơn trong việc xử lý đầu ra so với worker singleplex. Mọi nội dung được gửi đến stderr
sẽ được đưa vào một tệp nhật ký
được chia sẻ giữa tất cả WorkerProxy
cùng loại,
xen kẽ ngẫu nhiên giữa các yêu cầu đồng thời. Mặc dù bạn nên chuyển hướng stdout
vào stderr
, nhưng đừng thu thập đầu ra đó vào trường output
của WorkResponse
, vì điều đó có thể cho người dùng thấy các phần đầu ra bị xáo trộn.
Nếu công cụ của bạn chỉ gửi kết quả do người dùng hướng đến đến stdout
hoặc stderr
, bạn sẽ
bạn cần thay đổi hành vi đó thì mới có thể bật tính năng multiplex worker.
Bật worker đa kênh
Theo mặc định, Trình thực thi Multiplex không được bật. Một bộ quy tắc có thể bật tính năng multiplex
worker bằng cách sử dụng thẻ supports-multiplex-workers
trong
execution_requirements
của một hành động (giống như thẻ supports-workers
cho phép trình thực thi thông thường). Như trong trường hợp khi sử dụng trình thực thi thông thường, trình thực thi
chiến lược cần được chỉ định, ở cấp bộ quy tắc (ví dụ:
--strategy=[some_mnemonic]=worker
) hoặc thường ở cấp chiến lược (đối với
ví dụ: --dynamic_local_strategy=worker,standalone
.) Không có cờ bổ sung nào
cần thiết và supports-multiplex-workers
sẽ được ưu tiên hơn so với
supports-workers
, nếu bạn đã đặt cả hai. Bạn có thể tắt trình chạy đa năng trên toàn cục bằng cách truyền --noworker_multiplex
.
Bạn nên sử dụng quy tắc để sử dụng trình chạy đa kênh nếu có thể, nhằm giảm áp lực bộ nhớ và cải thiện hiệu suất. Tuy nhiên, các trình thực thi Multiplex hiện không tương thích với tính năng thực thi động trừ phi chúng hãy triển khai hộp cát multiplex. Đang cố chạy Multiplex không có hộp cát trình thực thi có tính năng thực thi động sẽ tự động sử dụng hộp cát thay thế cho singleplex.
Chạy trong môi trường hộp cát Multiplex
Bạn có thể đưa worker Multiplex vào hộp cát bằng cách thêm tính năng hỗ trợ tường minh cho worker đó trong quá trình triển khai worker. Mặc dù bạn có thể tạo hộp cát cho worker đơn bằng cách chạy từng quy trình worker trong hộp cát riêng, nhưng worker đa kênh sẽ chia sẻ thư mục hoạt động của quy trình giữa nhiều yêu cầu song song. Để cho phép hộp cát của các worker đa kênh, worker phải hỗ trợ việc đọc từ và ghi vào một thư mục con được chỉ định trong mỗi yêu cầu, thay vì trực tiếp trong thư mục đang hoạt động.
Để hỗ trợ hộp cát multiplex, worker phải sử dụng trường sandbox_dir
từ WorkRequest
rồi sử dụng giá trị này làm tiền tố cho tất cả lượt đọc và ghi tệp.
Mặc dù các trường arguments
và inputs
không thay đổi so với yêu cầu không có hộp cát, nhưng dữ liệu đầu vào thực tế lại liên quan đến sandbox_dir
. Worker phải
dịch đường dẫn tệp tìm thấy trong arguments
và inputs
để đọc từ tệp này
đường dẫn đã sửa đổi và cũng phải ghi tất cả kết quả tương ứng với sandbox_dir
.
Các đường dẫn này bao gồm các đường dẫn như "." cũng như các đường dẫn được tìm thấy trong các tệp đã chỉ định
trong các đối số (chẳng hạn như "argfile").
Sau khi một worker hỗ trợ tính năng hộp cát multiplex, bộ quy tắc có thể khai báo thông tin này
bằng cách thêm supports-multiplex-sandboxing
vào
execution_requirements
của một hành động. Sau đó, Bazel sẽ sử dụng hộp cát đa kênh nếu cờ --experimental_worker_multiplex_sandboxing
được truyền hoặc nếu worker được sử dụng với phương thức thực thi động.
Các tệp worker của worker đa kênh trong hộp cát vẫn tương ứng với thư mục đang hoạt động của quy trình worker. Do đó, nếu một tệp được dùng cả để chạy worker và làm dữ liệu đầu vào, thì tệp đó phải được chỉ định cả làm dữ liệu đầu vào trong đối số flagfile cũng như trong tools
, executable
hoặc runfiles
.