From ea1238e9d26b35e47a27102767d198321e7c2073 Mon Sep 17 00:00:00 2001 From: J Date: Tue, 23 Jun 2026 17:41:35 +0800 Subject: [PATCH] docs(channel): point migration 124 ROLLOUT note at the hub-disable switch Refine the rollout note to use MULTICA_LARK_HUB_DISABLED for a bot-only cutover (new pods serve API with the hub parked while old pods drain; flip the switch off after the migration), instead of the earlier whole-API recreate. Comment-only. MUL-3515 Co-authored-by: multica-agent --- .../124_channel_generalization.up.sql | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/server/migrations/124_channel_generalization.up.sql b/server/migrations/124_channel_generalization.up.sql index 3d6f655748..53c8b26e42 100644 --- a/server/migrations/124_channel_generalization.up.sql +++ b/server/migrations/124_channel_generalization.up.sql @@ -20,17 +20,24 @@ -- ship green on its own. This migration only ADDS channel_* and -- copies the data forward. -- --- * ROLLOUT — NON-ROLLING CUTOVER REQUIRED. This backfill is a one-time --- copy. After it runs, new code reads/writes channel_* while any --- pre-cutover (v0.3.x) code still reads/writes lark_*: the two table --- sets never cross-deduplicate, and each side would claim the same --- Feishu bot's WS lease on its own table and open a duplicate --- connection, double-processing inbound events (duplicate messages / --- /issue / runs). So old and new backend hub processes MUST NOT run --- concurrently against this schema — stop the old hub before applying --- this migration and starting the new code (recreate, not rolling). --- Rollback to a pre-cutover build is not lossless once the new code has --- written Feishu state into channel_*. +-- * ROLLOUT — Lark hub cutover required. This backfill is a one-time copy. +-- After it runs, new code reads/writes channel_* while any pre-cutover +-- (v0.3.x) code still reads/writes lark_*: the two table sets never +-- cross-deduplicate, and each side would claim the same Feishu bot's WS +-- lease on its own table and open a duplicate connection, double-processing +-- inbound events (duplicate messages / /issue / runs). So the old and new +-- Lark hubs MUST NOT run concurrently. The rollout uses the +-- MULTICA_LARK_HUB_DISABLED switch (cmd/server/main.go) to keep the hubs +-- from overlapping WITHOUT taking the whole API down: +-- 1. Ship the new release with MULTICA_LARK_HUB_DISABLED=true — new pods +-- serve HTTP but run no hub; old pods keep their lark_* hub until k8s +-- drains them, so only one hub is ever live. +-- 2. Once old pods are gone, run this migration (no hub is claiming). +-- 3. Flip the switch off — the new hub comes up on channel_*. +-- Only the Feishu bot is briefly unavailable (the window in 2-3); the API +-- stays up throughout. Rollback to a pre-cutover build is not lossless once +-- the new hub has written Feishu state into channel_*. See the PR +-- "Deployment / rollout" section for the full runbook. -- -- app_secret_encrypted is BYTEA; it is carried into the JSONB config as a -- base64 string. PostgreSQL's encode(...,'base64') MIME-wraps the output