From da70290087f9bbc2bf900625c3d66ec7b05bdd72 Mon Sep 17 00:00:00 2001 From: Aleksey Shugaev Date: Mon, 25 May 2026 12:24:30 +0000 Subject: [PATCH] Skip setupCheckers when SHUTDOWN_MODE is on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Production was unresponsive to /help even though the inbound shutdown middleware was in place: setupCheckers still spun up the price/shift updaters and the alert/shift checkers, which pegged the worker at ~100% CPU and starved the Telegraf polling loop so the farewell never made it out. Gate setupCheckers() on isShutdownMode(). When the flag is on the bot only initialises Telegraf to reply with the farewell — no cron, no price updaters, no alert/shift checkers, no payment polling. The lower-level notification gates in sendTriggeredAlert / checkTriggeredShiftsAndSendMessage stay as a defence-in-depth net for the case where the flag is toggled on a running instance. --- .env.sample | 11 ++++++++--- CONFIG.md | 2 +- src/app.ts | 10 ++++++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.env.sample b/.env.sample index 3b03803..fb54fc4 100644 --- a/.env.sample +++ b/.env.sample @@ -67,9 +67,14 @@ TRONSCAN_WALLET_ADDRESS= # ---- Optional: shutdown announcement --------------------------------------- -# Set SHUTDOWN_MODE=true to silence every handler, reply to incoming updates -# with the farewell in src/middlewares/shutdownMode.ts, AND stop every -# cron-driven outbound notification (price alerts, shift alerts). +# Set SHUTDOWN_MODE=true to wind the bot down without taking the process +# offline. The bot will: +# * silence every inbound handler and reply with the farewell in +# src/middlewares/shutdownMode.ts +# * skip starting setupCheckers() — no cron jobs, no price/shift updaters, +# no alert/shift checkers, no payment polling +# * additionally short-circuit each outbound notification path as a +# belt-and-suspenders safety net # Unset to restore the bot. SHUTDOWN_MODE= diff --git a/CONFIG.md b/CONFIG.md index c263d61..3ed974e 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -49,7 +49,7 @@ simply disable that data source. | Variable | Description | |----------|-------------| -| `SHUTDOWN_MODE` | Set to `true` to silence every inbound handler (replies with the farewell in `src/middlewares/shutdownMode.ts`) **and** stop every cron-driven outbound notification (price and shift alerts). Unset to restore the bot. | +| `SHUTDOWN_MODE` | Set to `true` to wind the bot down without taking the process offline. The inbound middleware (`src/middlewares/shutdownMode.ts`) replies with the farewell, `setupCheckers()` is skipped so no cron / price / shift / alert / payment loops start, and the outbound notification paths short-circuit as a safety net. Unset to restore the bot. | ## Optional: MongoDB tuning diff --git a/src/app.ts b/src/app.ts index d6c7d24..cb05262 100644 --- a/src/app.ts +++ b/src/app.ts @@ -42,6 +42,7 @@ import { setupStart } from './commands/start' import { setupStat, statScenes } from './commands/stat' import { bots } from './helpers/bot' import { setupI18N } from './helpers/i18n' +import { isShutdownMode } from './helpers/isShutdownMode' import { log } from './helpers/log' import { attachUser } from './middlewares/attachUser' import { checkTime } from './middlewares/checkTime' @@ -138,6 +139,15 @@ if (botConfig.appFlags.priceAlertBots) { botInit(bot) } + // Kill switch: when SHUTDOWN_MODE is on, only the inbound middleware + // (which replies with the farewell) needs to run. Skipping setupCheckers + // prevents the continuous price/shift loops from pegging CPU and + // starving the polling loop, so the farewell actually reaches users. + if (isShutdownMode()) { + log.info('SHUTDOWN_MODE is on; skipping cron jobs and monitoring loops.') + return + } + // Start all async tasks (cron and continuous) setupCheckers() })