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() })