v0.18.10:讓「同步引擎沒在跑」說出死因(leo Windows 實測①②的診斷前置)

leo 08-06 Windows 回報:「一直在『看守中』和『沒有在跑』中間閃,要我重啟但重啟無效,
我覺得它在跑個迴圈不停重複」+「加一個資料夾明顯沒產生看守資料夾」。
朋友的一般 PC(非 ARM)也一樣,停在等待中 ⇒ **不是 ARM 模擬的問題,是 Windows 通用**。

## 已定位的機制(不是根因,是「為什麼查不出根因」)
閃爍=子行程一啟動就死 → supervisor 退避重拉 → 狀態在 Starting(alive=true)與
Error(false)之間彈跳 ⇒ 畫面跟著閃。而**死因一直被記在 Status().LastError 裡,
從來沒有上過畫面、也沒寫進 app.log** ⇒ 使用者只看到閃爍與「請重新開啟」,
重開當然無效(死因沒變)。這是「安靜地略過」的同一種病換地方發作。

## 這版做的
- 死因上畫面:重試 >= 3 次改顯示「同步引擎一直啟動失敗,已自動重試 N 次|原因:…」,
  且**黏住不閃**(不受重起過程中的 Starting 影響)
- 每次異常結束寫進 app.log(同錯誤 10 次內只記一次,避免洗爆)

## 排除掉的嫌疑(查過,不是)
- PDF 引擎(pdfium/wasm):**延遲初始化**,第一次讀 PDF 才啟動 ⇒ 不會在啟動時炸
- ARM 模擬:leo 朋友的一般 x64 PC 同樣症狀
- 待查嫌疑:Wails 的 Windows 版是 `-H windowsgui`(GUI subsystem,無主控台),
  而 v0.18.8 的 collector.exe 是 `go build` 的 console subsystem——
  v0.18.9 合併成單一 binary 後,子行程換成 GUI subsystem 的自己。**尚未證實。**

## 順帶修好自己的閘(它擋對了我)
指紋閘擋下「v0.18.10 已對應另一份原始碼」——因為第一次打包失敗、版號卻已被戳。
⇒ 加判準:**磁碟上沒有該版號產物=從未出貨,允許重戳**(不用去手改 JSON,
那種爛示範遲早被改成「都放行」)。

## 安裝程式(leo ③)尚未兌現,誠實記錄
`wails build -nsis` 需要 makensis;Homebrew 的 3.12 在這台 macOS **連兩行的最小腳本
都在寫檔階段丟 std::bad_alloc**,zlib/bzip2/lzma 三壓縮器全崩,brew extract 舊版
被 homebrew/core 擋。且帶 -nsis 會讓 wails 整個中止、連 exe 都不產
⇒ build-win.sh 改成**先煙霧測試 makensis**,壞的就只出裸 exe 並大聲警告。
This commit is contained in:
2026-08-06 18:27:08 +08:00
parent 0b8bc83bd1
commit 6698f9fbda
6 changed files with 128 additions and 26 deletions
+19 -1
View File
@@ -78,6 +78,15 @@ def source_fingerprint():
return hashlib.sha256((tree + diff).encode()).hexdigest()[:16]
def artifacts_for(version):
"""磁碟上有沒有這個版號的產物(exe/dmg/msix)。有=真的出過東西,不准重戳。"""
dist = HERE / "dist"
if not dist.is_dir():
return []
return [f.name for f in dist.iterdir()
if version in f.name and f.suffix in (".exe", ".dmg", ".msix", ".zip")]
def check_or_record(version, stamp):
"""同一個版號只准對應一份原始碼;不同就擋下並說怎麼辦。"""
fp = source_fingerprint()
@@ -85,6 +94,15 @@ def check_or_record(version, stamp):
return
lock = json.loads(SOURCE_LOCK.read_text()) if SOURCE_LOCK.exists() else {}
known = lock.get(version)
# 🔴 2026-08-06:打包**失敗**時版號已被戳、產物卻沒生出來 ⇒ 那個版號被白白燒掉,
# 修完再打就被自己的閘擋下,只能去手改 JSON(爛示範,遲早有人順手改成「都放行」)。
# ⇒ 沒有任何產物的版號=**從未出貨**,本來就該可以重戳。
# 判準是「磁碟上有沒有這個版號的產物」,不是「我覺得它沒出貨」。
if known and known != fp and not artifacts_for(version):
print("%s 之前戳過但**沒有產出任何檔案**(打包失敗),視為未出貨 → 重新對應這次的原始碼"
% version, file=sys.stderr)
known = None
lock.pop(version, None)
if known and known != fp:
die("""%s 這個版號已經對應過另一份原始碼了(記錄 %s,現在 %s)。
@@ -98,7 +116,7 @@ def check_or_record(version, stamp):
- (用戶語言的更新內容)
然後重跑打包,版號會自動變成下一個。""" % (version, known, fp, version))
if stamp and not known:
if stamp and lock.get(version) != fp:
lock[version] = fp
SOURCE_LOCK.write_text(json.dumps(lock, indent=1, ensure_ascii=False) + "\n")