feat(wiki): 監控目錄頁改走專用存取庫,比對鍵改用裸 HASH

What:MONITOR_CONTENTS 改由 wiki-repo CONTENTS 解析並透過 wiki-contents.sh
upsert 寫入,MONITOR_{HASH} 仍走 wiki-repo MONITOR。目錄頁新增一欄裸 HASH 當
比對鍵,第一欄的絕對網址連結留給人看。主機名一律取短名。

Why:目錄頁集中之後兩頁不再同庫,[[...]] 只在同一個 wiki 內解析,連結必須改絕對
網址。比對鍵原本是含網址的儲存格,換主機、換存取庫或 URL 編碼有差就比對不到,
巡檢每 15 分鐘寫一次,重複列會累積得很快。

How:目錄頁解不出存取庫時不再中止巡檢——那一頁只是索引,內容頁寫成就照樣寫心跳。
內容頁寫不成仍然中止且不寫心跳,自咬環的前提沒有鬆動。

Who:jsc-assist
This commit is contained in:
2026-09-02 11:01:51 +08:00
parent d349a76b9c
commit 4bf99dde76
10 changed files with 134 additions and 61 deletions
+36 -26
View File
@@ -1,44 +1,54 @@
# 助理巡檢目錄
> 由 `jsc-assist` 維護。這是目錄頁 `MONITOR_CONTENTS`。
> 一列代表一台機器。雜湊來源是 `{主機名}/{登入帳號}`,所以一台機器一列、一頁,換一支 CLI 不另開列。
> `MONITOR_{HASH}` 的 `{HASH}` 交給 `jsc-gitea/tools/hash-id` 產生,雜湊來源見 `jsc-meta` 的 `references/guidelines.md`「Wiki 頁命名總表」。
> 由 `jsc-assist` 維護。這是目錄頁 `MONITOR_CONTENTS`,落在 `JSC_WIKI_REPO_CONTENTS` 解出的專用存取庫,和監控頁不同庫。
> 一列代表一台機器。雜湊來源是 `{主機名}/{登入帳號}`,主機名取短的那一段,所以一台機器一列、一頁,換一支 CLI 不另開列。
> `MONITOR_{HASH}` 的 `{HASH}` 執行 `jsc-gitea/tools/hash-id {主機名}/{登入帳號}` 取得,原樣採用它印出的完整 40 碼大寫十六進位,不截短、不加前綴(共用 wiki hash 規則,演算法見 `jsc-meta` 的 `references/guidelines.md`)。
>
> 連結寫法:監控頁那一欄放 `jsc-gitea/tools/gitea.sh wiki-url` 印出的絕對網址,不用 `[[...]]`。兩頁分屬不同存取庫,`[[...]]` 連不過去,畫面上還看不出壞掉。
>
> 比對鍵:第 2 欄的裸 HASH,純文字,不帶連結、不帶網址。連結那一欄是給人看的,不當鍵。
| 監控頁 | 主機 | 帳號 | 心跳 | 最後巡檢 | 待辦筆數 | 連續失敗項 |
| --- | --- | --- | --- | --- | ---: | ---: |
| [[MONITOR_{HASH}]] | {主機名} | {登入帳號} | {新鮮、過期、不存在 三選一} | {yyyy-MM-dd HH:mm} | {n} | {n} |
| 監控頁 | HASH | 主機 | 帳號 | 心跳 | 最後巡檢 | 待辦筆數 | 連續失敗項 |
| --- | --- | --- | --- | --- | --- | ---: | ---: |
| [MONITOR_{HASH}]({wiki-url 印出的絕對網址}) | {HASH} | {主機名} | {登入帳號} | {新鮮、過期、不存在 三選一} | {yyyy-MM-dd HH:mm} | {n} | {n} |
## 欄位說明
| 欄位 | 內容 | 為什麼留這一欄 |
| --- | --- | --- |
| 監控頁 | 指向 `MONITOR_{HASH}` 的同 wiki 連結 | 少了連結就要人自己算雜湊才翻得到內容頁 |
| 主機 | 這台機器的主機名,與雜湊第一段相同 | 比對用的兩欄之一,決定要更新哪一列 |
| 帳號 | 助理執行時的登入帳號,與雜湊第二段相同 | 比對用的兩欄之一。同一台機器換帳號就是另一個巡檢對象 |
| 監控頁 | 指向 `MONITOR_{HASH}` 的絕對網址連結,給人點的,不當比對鍵 | 少了連結就要人自己算雜湊才翻得到內容頁;跨存取庫只有絕對網址連得過去 |
| HASH | `hash-id` 印出的完整 40 碼大寫十六進位,純文字,不加連結、不加網址,也是 upsert 的比對鍵 | 這一格只跟 `{主機名}/{登入帳號}` 有關,換主機位址、換存取庫、換一種網址編碼都不會變。拿含網址的連結當鍵才會對不上,然後同一台機器每輪多附一列 |
| 主機 | 這台機器的短主機名,與雜湊第一段相同 | 一眼看出這一列是哪一台機器 |
| 帳號 | 助理執行時的登入帳號,與雜湊第二段相同 | 同一台機器換帳號就是另一個巡檢對象,雜湊也會不同 |
| 心跳 | 巡檢當下(本輪寫入前)的心跳判定,判準只看 `ts` 距現在有沒有超過門檻,預設 300 秒 | 一眼看出這台機器上一輪巡檢有沒有跑完,不必逐頁翻 |
| 最後巡檢 | 該頁最新一節的時間戳 | 心跳由巡檢寫,兩欄理當一致;差很多就代表有一輪寫了心跳卻沒寫頁,那是缺陷 |
| 最後巡檢 | 該頁最新一輪的時間戳 | 心跳由巡檢寫,兩欄理當一致;差很多就代表有一輪寫了心跳卻沒寫頁,那是缺陷 |
| 待辦筆數 | 待辦簿現有筆數 | 心跳新鮮而筆數為 0,代表助理空轉,沒有東西可跑 |
| 連續失敗項 | 該頁最新一節裡 `fail_count` 大於 0 的筆數 | 待辦簿的項目失敗不會自動暫停,每輪都重試。這一欄讓壞掉的項目在目錄頁就現形 |
| 連續失敗項 | 待辦簿裡 `fail_count` 大於 0 的筆數 | 待辦簿的項目失敗不會自動暫停,每輪都重試。這一欄讓壞掉的項目在目錄頁就現形 |
## 寫入規則
這一頁是共用目錄,別台機器的列一律原樣保留。
這一頁是共用目錄,別台機器的列一律原樣保留。寫入一律用 `jsc-gitea/tools/wiki-contents.sh upsert`,不手工改頁。
```mermaid
flowchart TD
A[整頁讀回來] --> B{讀得到舊內容}
B -- 否 --> C[中止:不新增列,也不寫入]
B -- 是 --> D{主機與帳號兩欄都對得上}
D -- 是 --> E[只覆寫那一列的其餘欄位]
D -- 否 --> F[新增一列]
E --> G[其他機器的列原樣送回]
F --> G
A[監控頁已經寫成] --> B[gitea.sh wiki-url 取監控頁絕對網址]
B --> C[組出本機那一列,網址換掉佔位]
C --> D[wiki-contents.sh upsert MONITOR 第 2 欄的裸 HASH 當鍵]
D --> E{舊頁讀得回來}
E -- 是 --> F{HASH 欄對得上}
F -- 是 --> G[取代那一列]
F -- 否 --> H[附加一列]
E -- 頁不存在 --> I[用範本建頁,再附加一列]
E -- 金鑰失效或 API 失敗 --> J[中止:不建頁、不寫入]
G --> K[整頁寫回,別台機器的列原樣送回]
H --> K
I --> K
```
- 先整頁讀回來,再比對主機與帳號兩欄。
- 兩欄都相同就更新那一列,其餘欄位覆寫成本次巡檢結果。
- 找不到兩欄都相同的列,才新增一列。
- 只動自己那一列,別台機器的列一個字都不改。
- 禁止整頁覆蓋。整頁覆蓋等於刪掉別台機器的紀錄。
- 讀不到舊內容就中止,不新增列,也不寫入。
- 內容頁 `MONITOR_{HASH}` 的寫入語意相反,那頁只附加一節、不覆寫,兩者不要混用。
- 存取庫走 `gitea.sh wiki-repo CONTENTS`:先 `JSC_WIKI_REPO_CONTENTS`,再 `JSC_WIKI_REPO`,都沒設就結束碼 3,不退回監控頁那一支變數。
- 比對鍵是第 2 欄的裸 HASH,原樣比對整格文字。鍵取 `collect` 印的 `hash=`,自己重打會對不上,結果是同一台機器多出第二列。
- 第一欄的連結不當鍵:那一格含 `GITEA_HOST` 與頁名的網址編碼,主機位址改掉、`JSC_WIKI_REPO_MONITOR` 換了存取庫、或 Gitea 的網址編碼有差,整格文字就變了,鍵跟著對不上。這一頁每 15 分鐘寫一次,對不上的那一刻起每輪多附一列,舊列再也不會更新。
- 找得到相同的 HASH 就更新那一列,找不到才附加一列。
- 只動自己那一列,別台機器的列一個字都不改。禁止整頁覆蓋——整頁覆蓋等於刪掉別台機器的紀錄。
- 只有「頁不存在」才准用範本建頁。金鑰失效或 API 失敗一律中止:那兩種情況舊內容是未知的,拿範本蓋上去就是把活著的紀錄整份刪掉。
- 內容頁 `MONITOR_{HASH}` 的寫入語意不同:那頁固定三塊,最新一輪整塊換掉,摘要表一輪一列、最新的在最上面、超過 24 列丟最舊的。兩者不要混用。
+5 -4
View File
@@ -4,7 +4,7 @@
> 這頁固定三塊:本頁基本資料、最新一輪、近 24 輪摘要。
> 最新一輪每輪整塊換掉;摘要表一輪一列往上疊,只留 24 列;基本資料建頁時寫一次就不動。
> 完整內容只留最新一輪,頁面才讀得完;軌跡留在摘要表,看得出是從哪一輪開始壞的。
> 目錄頁 `MONITOR_CONTENTS` 只更新自己那一列,別台機器的列一個字都不動。
> 目錄頁 `MONITOR_CONTENTS` 在 `JSC_WIKI_REPO_CONTENTS` 解出的專用存取庫,和這頁不同庫;那一頁只更新自己那一列,別台機器的列一個字都不動。
```mermaid
flowchart LR
@@ -13,7 +13,7 @@ flowchart LR
C --> D[換掉最新一輪那一塊]
D --> E[本輪摘要列插到表格最上面,截到 24 列]
E --> F[整頁寫回]
F --> G[更新 MONITOR_CONTENTS 自己那一列]
F --> G[wiki-contents.sh upsert 更新目錄頁自己那一列]
G --> H[最後才寫心跳]
```
@@ -135,5 +135,6 @@ flowchart LR
- 本輪的摘要列插到摘要表最上面,舊的列往下移,超過 24 列就丟掉最舊的那一列。
- 三塊重組成一整頁再整頁寫回。除了這三塊,頁上沒有別的東西。
- 舊格式的頁(一輪一節疊起來的那種)第一次重組時,基本資料留著,那些節收掉,摘要表從本輪這一列開始,並在回報裡說明。
- 整頁寫成之後,才回頭更新 `MONITOR_CONTENTS` 自己那一列,別台機器的列一個字都不動。
- 兩頁都寫成之後,才寫這一輪的心跳。任一頁沒寫成就不寫心跳,讓它過期。
- 整頁寫成之後,才回頭更新目錄頁自己那一列,寫入交給 `jsc-gitea/tools/wiki-contents.sh upsert`,別台機器的列一個字都不動。目錄頁那一欄的連結用絕對網址,兩頁不同庫,`[[...]]` 連不過去。
- 這一頁沒寫成就不寫心跳,讓它過期。心跳代表的是「這一輪的結果記在這一頁上了」。
- 目錄頁只是索引。目錄頁的存取庫沒設定(結束碼 3)時照樣寫心跳,並把那一筆列進待人處理;其餘寫入失敗才不寫心跳。