iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
自我挑戰組

30 天養大一個開源專案:baodao-skill 從零開始系列 第 28 篇

【Day 28】排程寫 12:17 UTC,26 次實測都晚了 3.2 到 7.4 小時才跑

  • 分享至 

  • xImage
  •  

前一篇的 10/3 排程 run 綠燈之後,我想知道那是不是運氣。2026-10-04 16:50 UTC 的排程 run 是第二個連續綠燈:run #77,commit 還是 b6d5b12,全程 1 分 0 秒。run #47、#51、#52、#63 連紅四次,現在連綠兩次,0.8.5 的修正算站穩了。這次的重點不在綠燈,是順手發現這個 run 的啟動時間跟我寫的 cron 差很多。

cron 寫的和實際跑的

.github/workflows/health-check.yml 裡排程是這樣寫的:

schedule:
  - cron: '17 12 * * *'

12:17 UTC 是台北時間 20:17。我一直以為每天晚上八點多會有一個結果。下面這段腳本把 Actions API 裡所有排程 run 的建立時間,跟 12:17 UTC 相比:

import json, statistics, urllib.error, urllib.request
from datetime import datetime

URL = 'https://api.github.com/repos/tahodev/baodao-skill/actions/runs?event=schedule&per_page=100'
try:
    runs = json.load(urllib.request.urlopen(URL, timeout=30))['workflow_runs']
except urllib.error.HTTPError as e:
    # 未登入每小時 60 次,超過會回 403,內文有 message
    raise SystemExit(f'GitHub API {e.code}: {e.read().decode()[:120]}')

late = []
for r in runs:
    t = datetime.fromisoformat(r['created_at'].replace('Z', '+00:00'))
    planned = t.replace(hour=12, minute=17, second=0)  # cron: 17 12 * * *
    hours = (t - planned).total_seconds() / 3600
    late.append(hours)
    print(r['created_at'], r['conclusion'], f'{hours:.1f}h')

print(len(late), 'runs, late min/median/max =',
      f'{min(late):.1f}h / {statistics.median(late):.1f}h / {max(late):.1f}h')

2026-10-05 04:54 KST 實測,輸出的前 3 行和最後 1 行:

2026-10-04T16:50:18Z success 4.6h
2026-10-03T16:14:47Z success 4.0h
2026-10-02T17:51:10Z failure 5.6h
...
26 runs, late min/median/max = 3.2h / 4.6h / 7.4h

從 9/9 到 10/4 是 26 天,API 回 26 個排程 run,沒有漏跑,但每一次都晚了 3.2 到 7.4 小時,中位數 4.6 小時。最近幾次換成台北時間:

排程 run 建立時間(台北) 晚了多久 結果
10/5 00:50 4.6 小時 success
10/4 00:14 4.0 小時 success
10/3 01:51 5.6 小時 failure
10/2 02:24 6.1 小時 failure
9/29 03:39 7.4 小時 success

26 次裡沒有一次是 20:17 左右跑的,最早是 9/12 的 23:31(台北),最晚是 9/29 的 03:39。文件裡寫得很直白:schedule 事件在 Actions 高負載時可能延遲,每個整點開頭特別擠,建議改到整點以外的時間(來源在文末)。我早就用了 :17 而不是 :00,還是晚了這麼多。原因我從 repo 這邊驗證不了,只能看到延遲是穩定存在的。另外,26 次裡有 15 次紅燈、11 次綠燈,我沒有逐一追紅燈的原因,光看延遲長短也看不出和成功失敗有關。

這對每天的檢查代表什麼

我這個系列固定在台北時間 00:35 發文,發文前會看最近一次排程 run。26 次裡,在 00:35 之前就已經建立的只有 9 次,另外 17 次是在 00:35 之後才跑。也就是說多數時候,發文那一刻「今天的排程 run」根本還不存在,我看到的是前一天的結果。

所以現在的做法是:不要找「今天日期的 run」,直接取最新一筆排程 run,記下它的建立時間和 commit,在文章裡用它實際的時間。這次寫 run #77 的 16:50 UTC,就是這個原因。如果想要固定時間拿到結果,排程只能當作「大概每天一次」的保險,不能當作準點的時鐘。

錯誤處理

這篇資料來源是 GitHub API,未登入每小時限 60 次。今天(2026-10-05 03:44 KST)我自己就用完了,API 回的是一段 JSON,內容開頭是 API rate limit exceeded。查額度和重置時間用 /rate_limit 這個端點:

curl -s https://api.github.com/rate_limit | jq -c .resources.core

當時輸出:

{"limit":60,"remaining":0,"reset":1791141751,"used":60}

reset 是 Unix 時間,換算是 04:22:31 KST。上面的腳本遇到 403 會用 SystemExit 印出訊息然後停下,不會拿一個空結果去算中位數。重置後(04:54)重跑,額度回到 59。

沒做的三項,今天重測還是一樣

2026-10-05 03:45 KST,用 curl -s -o /dev/null -m 15 -w '%{http_code}\n' -A 'Mozilla/5.0' <網址> 測:

網址 結果
https://tisvcloud.freeway.gov.tw/ 000(15 秒逾時)
https://soa.tainan.gov.tw/ 000(15 秒逾時)
https://data.kcg.gov.tw/ 000(15 秒逾時)
https://www.nhi.gov.tw/ 403

國道即時路況、台南和高雄的垃圾車資料,從我的環境依舊連不上,所以倉庫沒有新增這三項,roadmap 也沒有打勾。今天沒有改任何倉庫檔案,所以 CHANGELOG 沒有新增條目。

來源

  • GitHub Docs,schedule 事件的延遲說明(2026-10-05 讀取):https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows
  • 10/4 排程 run #77:https://github.com/tahodev/baodao-skill/actions/runs/37218238380
  • 10/3 排程 run:https://github.com/tahodev/baodao-skill/actions/runs/37136136935
  • workflow 檔:https://github.com/tahodev/baodao-skill/blob/main/.github/workflows/health-check.yml

上一篇
【Day 27】58 級距全部對上,只有 150,000 那級差 1 元:Python 的 round 踩到四捨五入
下一篇
【Day 29】15 次紅燈拆開來看:10 次是 counts 步驟的基準數太死,5 次是 URL 檢查
系列文
30 天養大一個開源專案:baodao-skill 從零開始 共 29 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言