持續性工作站可加快建構作業速度。如果 您在建構作業中重複執行動作,但啟動成本較高 跨動作快取的好處,建議您以自行建構的 以執行這些動作
Bazel 伺服器會使用 stdin
/stdout
與 worker 通訊。它支援使用通訊協定緩衝區或 JSON 字串。
工作站實作項目包含兩個部分:
建立 worker
持續性工作站必須符合以下幾項規定:
- 會從其
stdin
讀取 WorkRequests。 - 寫入
WorkResponses
(也只有
WorkResponse
) 加入其stdout
。 - 它接受
--persistent_worker
旗標。包裝函式必須可識別--persistent_worker
指令列標記,且只在 否則就必須進行一次性編譯並結束
如果你的程式符合這些要求,即可用來做為 工人!
工作要求
WorkRequest
包含 worker 的引數清單,
代表工作站可以存取的輸入內容的路徑摘要組合 (這並非
但您可以使用這項資訊進行快取) 和要求 ID (值為 0)
適用於單面工作站
注意:雖然通訊協定緩衝區規格使用的是「Snake case」(request_id
),
JSON 通訊協定會使用「駝峰式大小寫」(requestId
)。這份文件使用駝峰式大小寫
但在 JSON 範例中會說是蛇,無論問題為何
通訊協定相當卓越
{
"arguments" : ["--some_argument"],
"inputs" : [
{ "path": "/path/to/my/file/1", "digest": "fdk3e2ml23d"},
{ "path": "/path/to/my/file/2", "digest": "1fwqd4qdd" }
],
"requestId" : 12
}
您可以使用選用的 verbosity
欄位,向 worker 要求額外的偵錯輸出內容。輸出內容和方式完全由 worker 決定。較高
值代表更詳細的輸出結果。將 --worker_verbose
標記傳遞至 Bazel 會將 verbosity
欄位設為 10,但您可以手動使用較小或較大的值,以便產生不同數量的輸出內容。
選用的 sandbox_dir
欄位僅供支援多重沙箱的工作者使用。
工作回應
WorkResponse
包含要求 ID、零個或非零結束代碼,以及
輸出字串,用於說明處理或執行時遇到的任何錯誤
要求。output
欄位包含簡短說明;完整記錄可能會寫入 worker 的 stderr
。由於 worker 可能只會將 WorkResponses
寫入 stdout
,因此 worker 通常會將所用工具的 stdout
重新導向至 stderr
。
{
"exitCode" : 1,
"output" : "Action failed with the following message:\nCould not find input
file \"/path/to/my/file/1\"",
"requestId" : 12
}
根據 protobuf 的規範,所有欄位均為選填欄位。不過,Bazel 要求 WorkRequest
和對應的 WorkResponse
必須具有相同的要求 ID,因此如果要求 ID 非零,就必須指定該 ID。這是有效的 WorkResponse
。
{
"requestId" : 12,
}
request_id
為 0 表示「單複數」要求 (此要求使用)
無法與其他要求同時處理。伺服器會保證
指定的工作站收到僅 request_id
0 或僅包含 0 的要求
request_id
大於零。單一複雜要求是依序傳送
例如伺服器在收到
回應 (取消要求除外,請參閱下文)。
注意事項
- 每個通訊協定緩衝區前面都會加上其長度,格式為
varint
(請參閱MessageLite.writeDelimitedTo()
)。 - JSON 要求和回應的前面不會加上大小指標。
- JSON 要求的結構與 protobuf 相同,但會使用標準 JSON,並為所有欄位名稱使用駝峰式大小寫。
- 為了維持與 protobuf 相同的向前和向後相容性屬性,JSON 工作者必須容許這些訊息中的不明欄位,並使用 protobuf 預設值來處理缺少的值。
- Bazel 將要求儲存為 protobuf 檔案,並透過 protobuf 的 JSON 格式
取消
工作站可選擇允許在完成工作要求前取消工作要求。
這在與動態執行方面特別有用,因為該作業位於
遠端執行能夠定期中斷執行。如要允許取消,請將 supports-worker-cancellation: 1
新增至 execution-requirements
欄位 (請見下方說明),並設定 --experimental_worker_cancellation
標記。
取消要求是設定 cancel
欄位的 WorkRequest
(同樣地,取消回應是設定 was_cancelled
欄位的 WorkResponse
)。取消要求或取消時只能填寫其他欄位
回應是 request_id
,表示要取消的要求。對於單工單線工作站,request_id
欄位會是 0;對於多工單線工作站,則會是先前傳送的 WorkRequest
的非 0 request_id
。伺服器可能會傳送取消要求
工作,這時系統會取消 worker 已回應的要求
要求。
無論是否已取消,每則非取消 WorkRequest
訊息都必須回覆一次。伺服器傳送取消要求後,工作站可能會回應 WorkResponse
,其中 request_id
已設為 request_id
,而 was_cancelled
欄位則設為 true。也可以傳送一般的 WorkResponse
,但
系統會忽略「output
」和「exit_code
」欄位。
一旦針對 WorkRequest
傳送回應,工作站就不得再觸碰工作目錄中的檔案。伺服器可自由清除檔案,包括暫存檔案。
建立使用工作站的規則
您也需要建立規則,產生由 worker 執行的動作。建立使用工作站的 Starlark 規則就如同 建立任何其他規則
此外,規則必須包含 worker 本身的參照,且 它帶來的動作有一些要求
參照 worker
使用工作站的規則必須包含參照 worker 的欄位
因此您需要建立 \*\_binary
規則的執行個體
工作站的工作。如果工作站稱為 MyWorker.Java
,則相關規則可能如下:
java_binary(
name = "worker",
srcs = ["MyWorker.Java"],
)
這會建立「worker」標籤,參照的是工作站二進位檔。接下來 定義「使用」 worker 的規則。這項規則應包含一個屬性 是指工作站二進位檔
如果您建構的工作機器人二進位檔位於名為「work」的套件中,且位於建構作業的頂層,則屬性定義可能會是這樣:
"worker": attr.label(
default = Label("//work:worker"),
executable = True,
cfg = "exec",
)
cfg = "exec"
表示 worker 應建構為在執行平台上執行,而非在目標平台上執行 (也就是在建構期間將 worker 用作工具)。
工作行動要求
使用工作站的規則會建立讓 worker 執行的動作。這些 必須執行幾項操作
「arguments」欄位。這會取得字串清單,但是除了 是在啟動時傳遞至 worker 的引數。「arguments」清單中的最後一個元素是
flag-file
(@-preceded) 引數。工作站會根據每個 WorkRequest 讀取指定旗標檔案中的引數。您的規則可以將非啟動引數寫入此標記檔案。「execution-requirements」欄位,可接受含有
"supports-workers" : "1"
或"supports-multiplex-workers" : "1"
的字典,或兩者皆含。所有傳送至 worker 的動作都需要「arguments」和「execution-requirements」欄位。此外,應由 JSON 工作者執行的動作,必須在執行要求欄位中加入
"requires-worker-protocol" : "json"
。"requires-worker-protocol" : "proto"
也是有效的執行要求,但 proto 工作站不需要這項要求,因為這是預設值。您也可以在執行要求中設定
worker-key-mnemonic
。如果您要重複使用多種動作類型的可執行檔,並且想透過這個 worker 區分動作,這項功能就很實用。在動作過程中產生的暫存檔案應儲存在 工作站的目錄。即可啟用沙箱機制。
假設規則定義包含上述的「worker」屬性,除了代表輸入內容的「srcs」屬性、代表輸出的「output」屬性,以及代表 worker 啟動 args 的「args」屬性之外,對 ctx.actions.run
的呼叫可能會是:
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"]
)
如需其他範例,請參閱「實作持續性工作站」。
範例
Bazel 程式碼集使用 Java 編譯器工作站,以及整合測試中使用的範例 JSON 工作站。
您可以使用 鷹架 只需傳入正確的回呼,即可將任何 Java 型工具加到 worker。
如需使用工作站的規則範例,請參閱 Bazel 的worker 整合測試。
外部貢獻者已使用各種語言實作 worker,請參閱 Bazel 永續性 worker 的多語言實作。您可以在 GitHub 上找到更多範例!