fix(resource-rule): 上次裝到一半死掉的帳號要能再裝一次(Arcrun#123)
封測者 1.4.45 實撞: a namespace with this account ID and title already exists ⇒ 那個帳號從此永遠裝不起來,而錯誤訊息對用戶完全無法行動。 根因:rule.mjs 第 2c 段只問「有沒有已部署的 worker 綁著它」, 不問「這個名字在帳號上是不是已經存在」。註解裡「本來就沒有東西可丟」 漏掉一種狀態——資源已建、worker 還沒部署就中斷(逾時/關掉分頁/斷網)。 拆除 youlin 時親眼看到的 8 顆空殼 KV 是同一個形狀。 修法:2c 在 create 之前先查同名。找到同名資源時: · 呼叫端聲明了 createNameIsOurs → 接回那一顆(adopt + reclaimed 標記) · 沒聲明 → 停手,訊息帶 RES-NAME-TAKEN 錯誤碼讓用戶回報 createNameIsOurs 是接管的唯一依據,預設 false(fail-closed)。只有名字 推導自使用者自己的身分時才准聲明——安裝器的 arcrun-rag-<slugFromEmail(email)>-kv-<binding> 合格;acr 從 toml 讀到的 裸 binding 名(WEBHOOKS)不合格,因為用戶自己也可能用那個名字。 這不是把 #97 刪掉的「照名字 ensure」搬回來: ① #97 找不到就新建一顆頂上去(會弄丟資料);這裡找到才沿用, 找不到照舊新建,永遠不拿新的空資源頂替既有的 ② 排在「已部署綁定=事實」之後,名字只在沒有任何綁定可看時才有發言權 ③ #97 無條件相信名字;這裡要呼叫端先證明名字推導自用戶身分 順手補上假帳號的保真度:FakeCloudflare.createKvNamespace 原本不擋同名, 所以半殘帳號在測試裡看起來只是「多幾顆孤兒」,實際上是裝不起來—— 少了那一行,這個 bug 測不出來。fixture-account.mjs 也把 resourcesExist 與 deployed 拆開,才表達得出這個狀態。 驗證(皆為實跑): node shared/resource-rule/tests/half-finished-install.mjs → 全部通過(零依賴) cd cli && npm test → 73/73 pass sync-resource-rule --check → 三份副本皆與原稿一致 ⚠️ 只有規則這一半。安裝器要在 manifestRequirements 聲明 createNameIsOurs 才會生效,那一半在 arcrun-rag(D85)。 Refs: inkstone/Arcrun#123
This commit is contained in:
@@ -20,6 +20,27 @@
|
||||
`planResources()`(不寫入,只出計畫)與 `applyResourcePlan()`(有 blocker 就拒絕執行)分兩段,
|
||||
所以「被擋下的時候一顆資源都不會被建出來」是**結構上的保證**,不是靠誰記得寫 early return。
|
||||
|
||||
### 1.1 第 2 條的例外:上一次裝到一半死掉(Arcrun#123)
|
||||
|
||||
「沒有人綁過它」有**兩種**成因,第 2 條原本只想到第一種:
|
||||
|
||||
| | 名字在帳號上 | 有 worker 綁著 | 該怎麼做 |
|
||||
|---|---|---|---|
|
||||
| 新版本新增的 binding/全新帳號 | ❌ | ❌ | 新建(照舊) |
|
||||
| **上次安裝建到一半就中斷** | ✅ | ❌ | **接回那一顆**(否則 CF 回「title already exists」,這個帳號**永遠裝不起來**) |
|
||||
|
||||
接管同名資源的**唯一**依據是呼叫端在 `BindingRequirement` 上聲明 `createNameIsOurs: true`,
|
||||
意思是「這個名字是我用**使用者自己的身分**可重現地算出來的」——安裝器的
|
||||
`arcrun-rag-<slugFromEmail(email)>-kv-<binding>` 合格;`acr` 從 wrangler.toml 讀到的裸 binding 名
|
||||
(`WEBHOOKS`)**不合格**,因為使用者自己也可能拿那個名字去建東西。
|
||||
|
||||
沒聲明就撞名 ⇒ **停手**(訊息帶 `RES-NAME-TAKEN` 錯誤碼讓使用者回報,
|
||||
**不叫他自己去 Cloudflare 後台動手**)。
|
||||
|
||||
🔴 這**不是**把 #97 刪掉的「照名字 ensure」搬回來。差別:#97 是**找不到就新建一顆頂上去**
|
||||
(會把活著的實例洗成空的);這裡是**找到才沿用、找不到才照舊新建**,而且排在
|
||||
「已部署的綁定=事實」之後——名字永遠只在「確定沒有任何綁定可看」時才有發言權。
|
||||
|
||||
---
|
||||
|
||||
## 2. 為什麼在這裡,不在 cypher-executor 的 API
|
||||
|
||||
Reference in New Issue
Block a user