Add UptimeKuma support to v2

This commit is contained in:
Nexus 2024-03-04 12:39:45 +00:00
parent 3625ff5d4a
commit 1a3b0ff660
2 changed files with 63 additions and 0 deletions

3
setup.cfg Normal file
View file

@ -0,0 +1,3 @@
[flake8]
max-line-length=120
ignore=W293,W291

View file

@ -4,6 +4,10 @@ import logging
import sys import sys
import traceback import traceback
import typing import typing
from threading import Thread, Event
import time
import random
import httpx
import uvicorn import uvicorn
from web import app from web import app
@ -14,6 +18,52 @@ from discord.ext import commands
from rich.logging import RichHandler from rich.logging import RichHandler
from conf import CONFIG from conf import CONFIG
class KillableThread(Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.kill = Event()
class KumaThread(KillableThread):
def __init__(self, url: str, interval: float = 60.0):
super().__init__(target=self.run)
self.daemon = True
self.log = logging.getLogger("philip.status")
self.url = url
self.interval = interval
self.kill = Event()
self.retries = 0
def calculate_backoff(self) -> float:
rnd = random.uniform(0, 1)
retries = min(self.retries, 1000)
t = (2 * 2 ** retries) + rnd
self.log.debug("Backoff: 2 * (2 ** %d) + %f = %f", retries, rnd, t)
# T can never exceed self.interval
return max(0, min(self.interval, t))
def run(self) -> None:
with httpx.Client(http2=True) as client:
while not self.kill.is_set():
start_time = time.time()
try:
self.retries += 1
response = client.get(self.url)
response.raise_for_status()
except httpx.HTTPError as error:
self.log.error("Failed to connect to uptime-kuma: %r: %r", self.url, error, exc_info=error)
timeout = self.calculate_backoff()
self.log.warning("Waiting %d seconds before retrying ping.", timeout)
time.sleep(timeout)
continue
self.retries = 0
end_time = time.time()
timeout = self.interval - (end_time - start_time)
self.kill.wait(timeout)
log = logging.getLogger("jimmy") log = logging.getLogger("jimmy")
CONFIG.setdefault("logging", {}) CONFIG.setdefault("logging", {})
@ -45,8 +95,15 @@ class Client(commands.Bot):
def __init_(self, *args, **kwargs): def __init_(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.web: typing.Optional[asyncio.Task] = None self.web: typing.Optional[asyncio.Task] = None
self.uptime_thread = None
async def start(self, token: str, *, reconnect: bool = True) -> None: async def start(self, token: str, *, reconnect: bool = True) -> None:
if CONFIG["jimmy"].get("uptime_kuma_url"):
self.uptime_thread = KumaThread(
CONFIG["jimmy"]["uptime_kuma_url"],
CONFIG["jimmy"].get("uptime_kuma_interval", 60.0)
)
self.uptime_thread.start()
app.state.bot = self app.state.bot = self
config = uvicorn.Config( config = uvicorn.Config(
app, app,
@ -63,6 +120,9 @@ class Client(commands.Bot):
async def close(self) -> None: async def close(self) -> None:
if self.web: if self.web:
self.web.cancel() self.web.cancel()
if self.thread:
self.thread.kill.set()
await asyncio.get_event_loop().run_in_executor(None, self.thread.join)
await super().close() await super().close()