建立永久工作站

回報問題 查看原始碼 夜間 7.2 7.1 7.0 6.5 6.4

永久工作站可加快建構速度。如果 您在建構作業中重複執行某些動作,但啟動成本較高,或是 跨動作快取的好處,建議您以自行建構的 以執行這些動作

Bazel 伺服器使用 stdin/stdout 與工作站通訊。這項服務 支援使用通訊協定緩衝區或 JSON 字串。

工作站實作包含兩個部分:

讓工作站成為工作站

永久性工作站需要滿足以下幾項需求:

  • 讀取 WorkRequests 來自其 stdin
  • 寫入 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_verbose 標記傳送至 Bazel 會將 verbosity 欄位設為 10,但您可以使用較小或較大的值 以不同的輸出內容手動執行

sandbox_dir 選填欄位僅供支援的工作站使用 Multix 沙箱

工作回應

WorkResponse 包含要求 ID、零個或非零結束代碼,以及 輸出字串,用於說明處理或執行時遇到的任何錯誤 要求。output 欄位含有簡短說明;完整的記錄檔 寫入 worker 的 stderr。因為 worker 只能寫入 WorkResponsesstdout,工作站經常將 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。這是 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_cancelledWorkResponse 欄位集)。取消要求或取消時的唯一其他欄位 回應是 request_id,並指出要取消的要求。request_id 如果欄位是單一複雜工作站,則會是 0;如果先前為 0,則會傳回非 0 request_id 已為多工工作站傳送 WorkRequest。伺服器可能會傳送取消要求 工作,這時系統會取消 worker 已回應的要求 要求。

每則非取消的 WorkRequest 訊息都必須回答一次,無論是 並未取消伺服器傳送取消要求後,工作站可能會 以 request_idwas_cancelled 回應 WorkResponse ] 欄位設為 true。也可以傳送一般的 WorkResponse,但 系統會忽略「output」和「exit_code」欄位。

傳送回應給 WorkRequest 後,工作站不得碰觸 複製到工作目錄中的檔案伺服器可以免費清理檔案 包括暫存檔案

建立使用工作站的規則

您還需要建立規則,用來產生要由以下規則執行的動作 工作站建立使用工作站的 Starlark 規則就如同 建立任何其他規則

此外,規則必須包含工作站本身的參照,且 它帶來的動作有一些要求

參照工作站

使用工作站的規則必須包含參照 worker 的欄位 因此您需要建立 \*\_binary 規則的執行個體 工作站的工作。如果 worker 是 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 執行的動作。這些 必須執行幾項操作

  • "引數" 欄位。這會取得字串清單,但是除了 是在啟動時傳遞至 worker 的引數。中的最後一個元素 「引數」清單是 flag-file (@ 前置字元) 引數。工作站讀取數 指定旗標檔案中的引數。您的 規則可以將 worker 的非啟動引數寫入這個旗標檔案。

  • "execution-requirements" 欄位,這個欄位使用的字典含有 "supports-workers" : "1" 和/或 "supports-multiplex-workers" : "1"

    「引數」和「執行要求」所有必填欄位都必須填寫 傳送到 worker此外,凡是應該由 JSON 工作站需要將 "requires-worker-protocol" : "json" 包含在 執行需求欄位。"requires-worker-protocol" : "proto"也參與了 有效的執行要求,雖然對 proto 工作站並不需要 因為這是預設值

    您也可以在執行要求中設定 worker-key-mnemonic。這個 如果您要重複利用多個動作類型的執行檔, 可以區分此 worker 的動作

  • 在動作過程中產生的暫存檔案應儲存在 工作站的目錄。即可啟用沙箱機制。

假設規則定義中包含「worker」以及上述 「src」屬性,代表輸入的「輸出」屬性 代表輸出內容,「引數」代表 worker 的屬性 啟動引數,對 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 的 工作站整合測試

外部貢獻者以各種語言實作工作站;搭乘 CANNOT TRANSLATE Bazel 永久磁碟工作站的 Polyglot 實作。 你可以 前往 GitHub 查看更多範例