|
11 | 11 | from aiohttp import web |
12 | 12 | from aiohttp.web_ws import WebSocketResponse |
13 | 13 | import aiohttp_jinja2 |
| 14 | +from tenacity import ( |
| 15 | + AsyncRetrying, |
| 16 | + before_sleep_log, |
| 17 | + retry_if_exception_type, |
| 18 | + wait_exponential_jitter, |
| 19 | +) |
14 | 20 |
|
15 | 21 | from pythongettext.msgfmt import Msgfmt, PoSyntaxError |
16 | 22 | from sortedcollections import ValueSortedDict |
@@ -509,14 +515,32 @@ def __init_fishnet_monitor(self) -> dict: |
509 | 515 | def __init_discord(self): |
510 | 516 | if self.db is None: |
511 | 517 | self.discord = FakeDiscordBot() |
| 518 | + return |
512 | 519 |
|
513 | 520 | # create Discord bot |
514 | 521 | if DEV: |
515 | 522 | self.discord = FakeDiscordBot() |
516 | 523 | else: |
| 524 | + if DISCORD_TOKEN == "": |
| 525 | + log.warning("DISCORD_TOKEN is missing/empty; Discord bot disabled") |
| 526 | + self.discord = FakeDiscordBot() |
| 527 | + return |
| 528 | + |
517 | 529 | bot = DiscordBot(self) |
518 | 530 | self.discord = bot |
519 | | - asyncio.create_task(bot.start(DISCORD_TOKEN), name="Discord-BOT") |
| 531 | + asyncio.create_task(self.__run_discord_bot(bot, DISCORD_TOKEN), name="Discord-BOT") |
| 532 | + |
| 533 | + async def __run_discord_bot(self, bot: DiscordBot, token: str) -> None: |
| 534 | + # Keep retrying startup/login on transient failures so relay can recover |
| 535 | + # automatically after brief network/API hiccups during dyno boot. |
| 536 | + async for attempt in AsyncRetrying( |
| 537 | + retry=retry_if_exception_type(Exception), |
| 538 | + wait=wait_exponential_jitter(initial=1, max=120), |
| 539 | + reraise=True, |
| 540 | + before_sleep=before_sleep_log(log, logging.WARNING), |
| 541 | + ): |
| 542 | + with attempt: |
| 543 | + await bot.start(token) |
520 | 544 |
|
521 | 545 | def __init_twitch(self) -> Twitch: |
522 | 546 | result = Twitch(self.app) |
|
0 commit comments