feat: one Poll Lane per Site, replacing the shared pace (#100) (#106)

Closes #100.

Each Site runs its own Poll Lane: an independent goroutine with its own rest
and pace from the registry (`backend/internal/latest/sites.go`), replacing the
shared cooldown/interval/stagger/batch configuration. Rest (1h, all six Sites
including the browser trio) is enforced by the due query's WHERE clause; the
Lane sleeps its effective gap between fetches — the registry 10s, or
rest/eligible when a Site holds enough Series, floored at 1s with a
Site-naming warning when the floor engages.

Lane-local failure handling:
- Two challenge-held results stop that Site's Lane for 15m; the probes keep
  their stamp, untried Series stay due.
- A lost browser sets a shared Poller flag: the other browser Lanes skip
  their passes for the same 15m (no stamp-per-pass-per-Lane on a dead tab),
  then decay and probe again.
- Browser wake gate preserved (5 due, or one waiting 15m, ADR-0005); one tab
  shared by the three browser Sites; "browser lane behind by X" logged every
  pass.
- Cover work (healing a stored source URL and filling a blank from the series
  page) runs in the background so a slow CDN cannot consume a Lane's gap.

Removed: `LATEST_CHAPTER_POLL_{COOLDOWN,BROWSER_COOLDOWN,INTERVAL,BATCH,STAGGER}`
and the 6h browser rest. Only `LATEST_CHAPTER_POLL_ENABLED` remains; DEPLOY.md
documents the exact `.env` edit. ADR-0010 records the decisions.

Reviewed-on: #106
Co-authored-by: Sulthan Zaki <sultankiki05@gmail.com>
Co-committed-by: Sulthan Zaki <sultankiki05@gmail.com>
This commit was merged in pull request #106.
This commit is contained in:
2026-08-16 13:16:19 +07:00
committed by sulthan
parent ddbd57070d
commit 3303a55b20
22 changed files with 3645 additions and 1884 deletions
+50 -45
View File
@@ -25,9 +25,9 @@
"semantic_hash": "dac242903b0e98c3e4395159d609e08e"
},
"backend/main.go": {
"mtime": 1786501521.228955,
"ast_hash": "6e98a3ae91aaa132df251e43c4dfca6d",
"semantic_hash": "6e98a3ae91aaa132df251e43c4dfca6d"
"mtime": 1786859325.126449,
"ast_hash": "4ad77c286522f97d14b6009ff37118e5",
"semantic_hash": ""
},
"skills-lock.json": {
"mtime": 1784884678.6842625,
@@ -140,18 +140,18 @@
"semantic_hash": "3a08979e4603aae5c32a58d5b6c39765"
},
"CLAUDE.md": {
"mtime": 1786856633.445473,
"ast_hash": "fab288c23be960d9c6afbfe3f21ff41c",
"mtime": 1786857336.6414917,
"ast_hash": "c79e49f912d7852f9832565a5f9a1c39",
"semantic_hash": ""
},
"DEPLOY.md": {
"mtime": 1786501942.7367291,
"ast_hash": "3c7b785c44badb6dda6234d2b39a9290",
"mtime": 1786859620.9977603,
"ast_hash": "b7c2f813aded562ee9291c9baed795ad",
"semantic_hash": ""
},
"README.md": {
"mtime": 1786499529.7651505,
"ast_hash": "9d6be8aa8a2946c23ad48d8f2864b5ca",
"mtime": 1786859273.3238454,
"ast_hash": "81af12a0a2d43e791efd030b5f4d6cbc",
"semantic_hash": ""
},
"docker-compose.prod.yml": {
@@ -160,8 +160,8 @@
"semantic_hash": "0751998a532297b8ac507a01ec48dc31"
},
"docker-compose.yml": {
"mtime": 1786499529.7725692,
"ast_hash": "124fd581bf0a662ff15012abfdb40a92",
"mtime": 1786859258.6255276,
"ast_hash": "d3b53a8f42a8e0acb4fc4306ea42c093",
"semantic_hash": ""
},
".claude/settings.json": {
@@ -175,9 +175,9 @@
"semantic_hash": "8f1b093b59eb1ed81bc7fc0c22495c50"
},
"backend/main_test.go": {
"mtime": 1786501521.228955,
"ast_hash": "8a165955cf28ad47481fec5ea7afb3d6",
"semantic_hash": "8a165955cf28ad47481fec5ea7afb3d6"
"mtime": 1786859172.6449091,
"ast_hash": "0a5d4dbdc770b40c329ccccc899b59f4",
"semantic_hash": ""
},
".claude/settings.local.json": {
"mtime": 1785697645.350201,
@@ -200,8 +200,8 @@
"semantic_hash": "e69a8340a371579ca3ea689660f7d7bd"
},
"AGENTS.md": {
"mtime": 1786856633.445473,
"ast_hash": "fab288c23be960d9c6afbfe3f21ff41c",
"mtime": 1786857336.6414917,
"ast_hash": "c79e49f912d7852f9832565a5f9a1c39",
"semantic_hash": ""
},
"userscript/test/logic.test.js": {
@@ -215,7 +215,7 @@
"semantic_hash": "8f3c0132eb4787a2c8736eb99f7689af"
},
"REDEPLOY.md": {
"mtime": 1786856643.0770833,
"mtime": 1786857336.6414917,
"ast_hash": "e5e910f0244a040e2ccdc669b17eb4db",
"semantic_hash": ""
},
@@ -245,12 +245,12 @@
"semantic_hash": "385b36f58488b7e6d93eb6d6034e9ee3"
},
"backend/internal/latest/browser.go": {
"mtime": 1786856879.3397639,
"ast_hash": "fbdba4bb56d8c804087bcb6e141e52ad",
"mtime": 1786859355.8677974,
"ast_hash": "75f34a974568d122681939dd297944a2",
"semantic_hash": ""
},
"backend/internal/latest/browser_test.go": {
"mtime": 1786856254.36163,
"mtime": 1786857336.6414917,
"ast_hash": "800fa6aa471ada054a3c48943ad17ab7",
"semantic_hash": ""
},
@@ -260,22 +260,22 @@
"semantic_hash": ""
},
"backend/internal/latest/poller.go": {
"mtime": 1786856670.129715,
"ast_hash": "6b7060ff52994729832d9fcc3cc97dad",
"mtime": 1786860083.6713927,
"ast_hash": "be728405cde3df49baf72bd7837f2971",
"semantic_hash": ""
},
"backend/internal/latest/poller_test.go": {
"mtime": 1786856311.8535168,
"ast_hash": "b6837fab377c94fa1d2f20a931975a4a",
"mtime": 1786860168.103984,
"ast_hash": "5dba515d28c0523500c1ceb581a54e58",
"semantic_hash": ""
},
"backend/internal/latest/sites.go": {
"mtime": 1786856865.4529688,
"ast_hash": "2f00456ac9d1d8148ba1bc6cbceb24f6",
"mtime": 1786860007.8224697,
"ast_hash": "9b90f9b710ccbd0d0a0a6a0dd721ff3c",
"semantic_hash": ""
},
"backend/internal/latest/sites_test.go": {
"mtime": 1786856890.1231265,
"mtime": 1786857336.6414917,
"ast_hash": "0db2028a6073f342fee61ad15c2e5f0f",
"semantic_hash": ""
},
@@ -340,14 +340,14 @@
"semantic_hash": "0b6764a0ee20f5cb7748eecd31a1d220"
},
"backend/internal/store/store.go": {
"mtime": 1786363889.5602942,
"ast_hash": "54367a8ab043983e2491b2eb2650961c",
"semantic_hash": "54367a8ab043983e2491b2eb2650961c"
"mtime": 1786860012.3431706,
"ast_hash": "c62e73142386c58ab833d404d0c24dc4",
"semantic_hash": ""
},
"backend/internal/store/store_test.go": {
"mtime": 1786363889.5602942,
"ast_hash": "dc823fd77bcce2268114e31d759b20a5",
"semantic_hash": "dc823fd77bcce2268114e31d759b20a5"
"mtime": 1786858248.9426548,
"ast_hash": "039729554517960d1ae98f8409baf4ba",
"semantic_hash": ""
},
"backend/internal/userscript/userscript.go": {
"mtime": 1786216141.692644,
@@ -415,8 +415,8 @@
"semantic_hash": "e44a2f6f624db044e19508bc5ab05592"
},
"CONTEXT.md": {
"mtime": 1786855457.9327722,
"ast_hash": "24548f60414b4c5ff58538acaada5345",
"mtime": 1786859395.4497814,
"ast_hash": "4aafbce0b046e6e34734fb414df818ce",
"semantic_hash": ""
},
"CUTOVER.md": {
@@ -425,13 +425,13 @@
"semantic_hash": "6c6f3e4c4c2f57867894280bce728c50"
},
"backend/AGENTS.md": {
"mtime": 1786856656.6826186,
"ast_hash": "d5610ba24076b57e17b9d76241acaa65",
"mtime": 1786860230.7890837,
"ast_hash": "7ceec7c4576f6e91eaf02c200a0dd1b3",
"semantic_hash": ""
},
"backend/CLAUDE.md": {
"mtime": 1786856656.6826186,
"ast_hash": "d5610ba24076b57e17b9d76241acaa65",
"mtime": 1786860230.7890837,
"ast_hash": "7ceec7c4576f6e91eaf02c200a0dd1b3",
"semantic_hash": ""
},
"backend/internal/web/templates/app.html": {
@@ -560,7 +560,7 @@
"semantic_hash": "46cf7822d4f667e3cab36b547abe5e97"
},
"backend/internal/latest/cover.go": {
"mtime": 1786856664.2957466,
"mtime": 1786857336.6414917,
"ast_hash": "d5f2248c3d11de74bf5a3977651b17c2",
"semantic_hash": ""
},
@@ -570,8 +570,8 @@
"semantic_hash": "60d9eb7c59a3751baf4f31c7655217e7"
},
"backend/internal/latest/acquire.go": {
"mtime": 1786499529.7688599,
"ast_hash": "6c1ad34bbe9f5b49d0fd1eae9093f55d",
"mtime": 1786859346.3297389,
"ast_hash": "d605e3c94a62fc7787efbc139696b9d2",
"semantic_hash": ""
},
"backend/internal/latest/acquire_test.go": {
@@ -615,8 +615,8 @@
"semantic_hash": ""
},
"backend/internal/latest/read.go": {
"mtime": 1786499529.7688599,
"ast_hash": "3cf29046ddaef39fafb1df70b9f9ae8c",
"mtime": 1786859355.8679621,
"ast_hash": "9f039cc3ad74f803d7621f7ef4157bf2",
"semantic_hash": ""
},
"docs/research/cloudflare-bot-scoring-and-poll-cadence.md": {
@@ -625,8 +625,13 @@
"semantic_hash": ""
},
"backend/internal/latest/smoke_comix_test.go": {
"mtime": 1786856356.3432186,
"mtime": 1786857336.6414917,
"ast_hash": "111fdbb75fc68ac2ab1013bc916063cf",
"semantic_hash": ""
},
"docs/adr/0010-poll-lanes-per-site-pace.md": {
"mtime": 1786860214.4637265,
"ast_hash": "dc19d75f034ca920d93b9c71e6ca28e6",
"semantic_hash": ""
}
}