部署與輪詢
誰: 部署需要部門管理者;任何成員都可輪詢。沒有 streaming — 用輪詢。
1. 排入
POST {BASE}/private/module/edge-workers/worker/deployments
{"version_id": "<version.id>", "base_revision": <worker.latest_revision>}要在同一步驟中變更逐操作存取,請加上 operation_settings(即 PUT /worker/operation-settings 接受的物件;撰寫方式見管理逐操作存取):
POST {BASE}/private/module/edge-workers/worker/deployments
{"version_id": "<version.id>", "base_revision": <worker.latest_revision>,
"operation_settings": {"base_revision": <live settings revision>,
"operations": [{"operation_id": "<operationId>", "access": {"mode": "teamsync_internal"}}]}}- 部署時,
operations只列出你要變更的操作。請求中列出的列會覆蓋上線列;兩個 release 都有、但沒有列出的操作,保留完整的上線列(存取、金鑰、金鑰擁有權、服務帳號綁定);不在目標 manifest 中的操作會被丟棄。 operation_settings.base_revision是對上線 release 執行GET /worker/operation-settings所得的設定修訂版。設定會在目標 release 開始服務之前先暫存。- 也可以省略
operation_settings:上線 release 已持有設定表時,該表會自動帶到目標 release。 teamsync-worker deployCLI 指令只送出version_id與base_revision;operation_settings請改用 API 送出。
202 回傳 EdgeWorkerDeploymentStatus 票證,通常是 status: "submitting"。耐久意圖在派送前就先提交,所以完全相同的重複請求(同樣的 body、同樣的 operation_settings)會回同一張票證而不做新工作。地端在備份圍欄期間,票證顯示 status: "pending" 並帶 error_code: "edge_host_fenced";圍欄結束時才開始執行。
必須處理的錯誤
detail 是字串,或帶代碼的物件 {code, message};是物件時,請依 detail.code 分支。精確字串也列在錯誤。
| 回應 | 意義 | 處理方式 |
|---|---|---|
409 Worker revision changed; refresh before deploying | 期間有人提交或部署了 | GET /worker 拿新的 latest_revision。永遠不要盲目把數字加一重試 |
409 {"code":"worker_serving_target_unavailable","message":"Worker deployment target cannot be verified"} | 後端無法確認是哪個 Worker 位置在服務該 Worker 的上線 release(例如該 release 還沒有經過驗證的位置,或 Worker 的紀錄在那一刻被另一項操作鎖住);沒有排入任何工作。在排入步驟內發生競態時,同樣的情況會以純字串 Worker deployment target cannot be verified 出現;當此環境所設定的預設位置無法使用時(屬於平台設定問題),Worker 的第一次部署也可能得到純字串 Worker deployment target is unavailable | 稍等片刻後重試一次;若持續發生,告知平台維運者,該 Worker 的位置須先由其驗證才能部署 |
409 worker_migration_in_progress | 純字串:平台維運者正在把這個 Worker 搬到另一個位置,而搬移尚未結束(搬移 Worker);沒有排入任何工作。已持有逐操作設定的 Worker,或帶有 operation_settings 的請求,則改得到 503 Department Worker control change is unavailable(部署會透過一次有稽核的變更暫存那些設定),而在搬移短暫暫停期間,部署會在讀取現行設定時碰上被凍結的 Worker,回 409 Operation-settings revision is stale | 待搬移完成、回滾或放棄後重試 |
409 {"code":"deployment_in_progress","message":"Operation settings cannot change during a deployment"} | 本部門有一張部署票證仍是 pending、leased 或 uncertain(即使你沒送出設定,訊息仍寫 “settings”) | 輪詢你手上的票證;uncertain 需要公司管理者修復 |
409 {"code":"deployment_in_progress","message":"Another Worker settings mutation or deployment is in progress"} | 本部門另一個部署或操作設定寫入持有部門層級的鎖(最長 600 秒) | 稍等片刻後重試 |
409 a deployment is already active for this department Worker | 兩個請求在 outbox 內發生競態;一般路徑下你拿到的會是上面那個帶代碼的 409 | 先輪詢,再重試 |
409 Worker version cannot deploy from state '<state>' / Worker version was superseded; V2 rollback is not supported | 只有 ready 修訂版能部署,且永不倒退 | 改為提交新修訂版 |
409 uncertain deployment requires company reconciliation | 被鎖住,直到公司管理者執行修復 | 升級處理 |
409 {"code":"operation_settings_dedupe_mismatch","message":"Deployment settings differ from the existing ticket"} | version_id 與 base_revision 都和既有票證相同,但 operation_settings 不同(或一邊帶設定、一邊不帶);競態時字串為 operation-settings digest differs from the existing deployment | 重送原本的 body 以讀取該票證 |
409 Operation-settings revision is stale | operation_settings.base_revision 不是上線的設定修訂版 | 重新讀取設定,再重送 |
409 operation_settings_require_supported_release | Deploy the Worker once before adding operation settings、The live release does not support operation settings 或 The target release does not support operation settings(上線 release 為 v2.8 或更新、目標較舊:即使沒帶設定也拒絕) | 重新上傳專案(會以目前的 builder policy 重新建置),再部署新修訂版 |
409 {"code":"operation_settings_pending","message":"Reconcile the live release before deploying settings"} | 上線 release 還沒有自己的設定表 | 先調解上線 release 的設定(管理逐操作存取) |
409 service_account_credentials_require_supported_release | Unbind every service account (PUT operation-settings) before deploying a release without service-account support,或設定引用了服務帳號、但目標/上線 release 早於 v2.9 | 解除綁定,或重新上傳並部署;見服務帳號 |
422 type: "operation_not_found" | 所列的 operation_id 不在目標 release 的 manifest 中 | 修正清單 |
422 type: "service_account_not_found" | 被引用的服務帳號不是本部門存活的服務帳號 | 修正 id |
503 Edge Worker provider is not configured | 平台的 provider 設定不合法;沒有排入任何工作 | 告知維運人員 |
503 Operation-settings mutation lock is unavailable | Redis 鎖無法使用 | 稍後重試 |
503 {"code":"operation_settings_live_read_unavailable","message":"Retry the deployment after the live settings read recovers"} | 上線 release 連續兩次沒有回應設定讀取 | 稍後重試 |
503 {"code":"api_base_unconfigured", ...} | 設定引用了服務帳號,但部署的 API base 未設定 | 告知維運人員 |
503 Deployment dispatch is unavailable | transport 確定沒有接下工作;(若先前有回傳)票證會是 failed 且 error_code: "dispatch_not_accepted" | 之後可以安全地重新 POST |
409 edge_workers_maintenance / edge_workers_restore_pending | 僅限地端:resync epoch 進行中,或還原保護開啟中;雲端永遠不會回這兩個 | 待維運人員完成後重試(地端) |
在 v2.6 或更新的上線 release 上,部署以早於 department-worker-project-v2.6 的 builder policy 建置的修訂版,會在上傳之前清除每一個 Worker 機密。見版本與部署。
2. 輪詢
GET {BASE}/private/module/edge-workers/worker/deployments/{ticket_id}| 狀態 | 意義 | 動作 |
|---|---|---|
submitting / pending | 排隊中(耐久提交前/後);地端帶 error_code: "edge_host_fenced" 的 pending 是在等備份圍欄 | 續輪詢 |
leased / deploying | 有 worker 認領/provider 上傳進行中,之後是等待已上傳的 release 回應(最長 600 秒) | 續輪詢 |
completed | 已結算:回讀吻合、release 已回應、Worker active、修訂版成為 current | 完成 |
failed | 終態;provider 證明未被觸及(或明確拒絕) | 讀 error_code,修正後重新提交/部署 |
cancelled | 終態(清理側字彙;部署不會產生) | — |
uncertain | 非終態 — provider 結果未知;Worker paused、准入被圍欄 | 升級給公司管理者做修復 |
合理頻率:約 1 秒(CLI 預設;deploy --wait 240 秒逾時,非 completed 一律以非零碼結束)。票證可從耐久列無限期讀取;Redis 鏡像只補充 leased 列,永遠無法讓終態倒退。
一次部署在上傳之後,最多可能要 10 分鐘才回報就緒。 先進行上傳及其回讀,然後任務會等新的 release 在其控制通道上回應,最長 600 秒(後端 5.22.0 之前是 60 秒),所以票證可能有好幾分鐘讀作 leased 或 deploying,最後仍以 completed 結束:在 600 秒內回應的 release 會結算為 completed,更慢的仍以 uncertain(worker_readiness_timeout)收場。在較新的 runtime 上重建既有的 Worker,可能要好幾分鐘才回報就緒;部署現在最多等 600 秒。請持續輪詢到票證進入終態,不要重新提交。票證在等待期間,Worker 為 paused:閘道通道的呼叫得到 404 Department Worker not found,新的部署得到 409 deployment_in_progress。teamsync-worker deploy --wait 預設在 240 秒後放棄,比這段等待還短:請傳入大於 600 000 的 --timeout-ms(例如 720 000),或改用 status <ticket> 接續追蹤(CLI)。
值得留意的 failed 錯誤代碼:department_deleted(部門在部署排隊期間被刪除;沒有上傳任何東西,結果是最終的,見退役)、edge_workers_provider_invalid(平台設定問題;告知維運人員)、artifact_integrity_failed、dispatch_not_accepted,以及自後端 5.22.0 起的 legacy_serving_target_unavailable、deployment_target_unavailable 與 deployment_target_release_changed(任務無法把票證對應到服務該 Worker 的位置;這次嘗試沒有上傳任何東西 — 請再部署一次,若被 409 worker_serving_target_unavailable 拒絕,請平台維運者驗證該 Worker 的位置)。完整清單:錯誤。
3. 「completed」證明了什麼
任務驗證了每個儲存摘要、按雜湊從 R2 讀回兩個產物、上傳了精確的 bundle,且只在 Cloudflare settings 與 Worker Details 兩個回讀都吻合預期 release 身分(compatibility date、無 flags、恰好一個 DO binding + SQLite export、吻合的 release-… tag),且上傳的 release 隨後在就緒輪詢中回應了簽章控制通道上唯讀的 access_policy.get(最長 600 秒)時才接受結算 — 與閘道呼叫走的是同一條 dispatcher 路徑。然後前一個修訂版變 superseded、這個變 deployed、Worker 變 active。機制:版本與部署。
uncertain 的實務意義
uncertain 表示模糊的 provider 結果(逾時、5xx、甚至 409/408 — 任何可能已到達 Cloudflare 的情況),且自動的 GET-only 調解已在嘗試預算內無法結案 — 或上傳後回讀吻合、但 release 在 600 秒的等待內始終沒有回應就緒檢查(error_code: "worker_readiness_timeout")。Worker 維持 paused(閘道呼叫准入被擋;已部署的程式碼(若有)仍繼續服務公開通道),也不再准入新部署。復原手段是公司管理者的修復 — 重新執行唯讀調解,永不盲目重新上傳。