Skip to content

Commit

Permalink
feat(webapp): monitor degraded status (#376)
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher authored Dec 15, 2024
1 parent ba4c842 commit 8468697
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 6 deletions.
17 changes: 15 additions & 2 deletions src/common/webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from werkzeug.middleware.proxy_fix import ProxyFix

# local imports
from src.common.common import app_dir, colors
from src.common.common import app_dir, colors, version
from src.common import crypto
from src.common import globals
from src.common import time
Expand Down Expand Up @@ -77,7 +77,20 @@ def html_to_md(html: str) -> str:

@app.route('/status')
def status():
return "LizardByte-bot is live!"
degraded_checks = [
getattr(globals.DISCORD_BOT, 'DEGRADED', True),
getattr(globals.REDDIT_BOT, 'DEGRADED', True),
]

s = 'ok'
if any(degraded_checks):
s = 'degraded'

result = {
"status": s,
"version": version,
}
return jsonify(result)


@app.route("/favicon.ico")
Expand Down
11 changes: 10 additions & 1 deletion src/discord/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def __init__(self, *args, **kwargs):
kwargs['auto_sync_commands'] = True
super().__init__(*args, **kwargs)

self.DEGRADED = False

self.bot_thread = threading.Thread(target=lambda: None)
self.token = os.environ['DISCORD_BOT_TOKEN']
self.db = Database(db_path=os.path.join(data_dir, 'discord_bot_database'))
Expand Down Expand Up @@ -122,7 +124,12 @@ async def async_send_message(
embed.description = embed.description[:-cut_length] + "..."

channel = await self.fetch_channel(channel_id)
return await channel.send(content=message, embed=embed)

try:
return await channel.send(content=message, embed=embed)
except Exception as e:
print(f"Error sending message: {e}")
self.DEGRADED = True

def send_message(
self,
Expand Down Expand Up @@ -273,10 +280,12 @@ def start_threaded(self):
self.bot_thread.start()
except KeyboardInterrupt:
print("Keyboard Interrupt Detected")
self.DEGRADED = True
self.stop()

def stop(self, future: asyncio.Future = None):
print("Attempting to stop tasks")
self.DEGRADED = True
self.daily_task.stop()
self.role_update_task.stop()
self.clean_ephemeral_cache.stop()
Expand Down
8 changes: 6 additions & 2 deletions src/reddit/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
class Bot:
def __init__(self, **kwargs):
self.STOP_SIGNAL = False
self.DEGRADED = False

# threads
self.bot_thread = threading.Thread(target=lambda: None)
Expand Down Expand Up @@ -57,8 +58,7 @@ def __init__(self, **kwargs):
self.migrate_shelve()
self.migrate_last_online()

@staticmethod
def validate_env() -> bool:
def validate_env(self) -> bool:
required_env = [
'DISCORD_REDDIT_CHANNEL_ID',
'PRAW_CLIENT_ID',
Expand All @@ -69,6 +69,7 @@ def validate_env() -> bool:
for env in required_env:
if env not in os.environ:
sys.stderr.write(f"Environment variable ``{env}`` must be defined\n")
self.DEGRADED = True
return False
return True

Expand Down Expand Up @@ -165,6 +166,7 @@ def discord(self, submission: models.Submission):
try:
redditor = self.reddit.redditor(name=submission.author)
except Exception:
self.DEGRADED = True
return

# create the discord embed
Expand Down Expand Up @@ -266,11 +268,13 @@ def start_threaded(self):
self.bot_thread.start()
except KeyboardInterrupt:
print("Keyboard Interrupt Detected")
self.DEGRADED = True
self.stop()

def stop(self):
print("Attempting to stop reddit bot")
self.STOP_SIGNAL = True
self.DEGRADED = True
if self.bot_thread is not None and self.bot_thread.is_alive():
self.comment_thread.join()
self.submission_thread.join()
Expand Down
50 changes: 50 additions & 0 deletions tests/unit/common/test_common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# standard imports
import os
import re

# lib imports
import pytest

# local imports
from src.common import common


@pytest.fixture(scope='module')
def github_email():
return '[email protected]'


def test_colors():
for color in common.colors.values():
assert 0x000000 <= color <= 0xFFFFFF, f"{color} is not a valid hex color"


def test_get_bot_avatar(github_email):
url = common.get_bot_avatar(gravatar=github_email)
print(url)
assert url.startswith('https://www.gravatar.com/avatar/')


def test_get_avatar_bytes(github_email, mocker):
mocker.patch('src.common.common.avatar', common.get_bot_avatar(gravatar=github_email))
avatar_bytes = common.get_avatar_bytes()
assert avatar_bytes
assert isinstance(avatar_bytes, bytes)


def test_get_app_dirs():
app_dir, data_dir = common.get_app_dirs()
assert app_dir
assert data_dir
assert os.path.exists(app_dir)
assert os.path.exists(data_dir)
assert os.path.isdir(app_dir)
assert os.path.isdir(data_dir)
assert app_dir == (os.getcwd() or '/app')
assert data_dir == (os.path.join(os.getcwd(), 'data') or '/data')


def test_version():
assert common.version
assert isinstance(common.version, str)
assert re.match(r'^\d+\.\d+\.\d+$', common.version)
19 changes: 18 additions & 1 deletion tests/unit/common/test_webapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,31 @@ def test_client():
yield test_client # this is where the testing happens!


def test_status(test_client):
@pytest.mark.parametrize("degraded", [
False,
True,
])
def test_status(test_client, discord_bot, degraded, mocker):
"""
WHEN the '/status' page is requested (GET)
THEN check that the response is valid
"""
# patch reddit bot, since we're not using its fixture
mocker.patch('src.common.globals.REDDIT_BOT', Mock(DEGRADED=False))

if degraded:
mocker.patch('src.common.globals.DISCORD_BOT.DEGRADED', True)

response = test_client.get('/status')
assert response.status_code == 200

if not degraded:
assert response.json['status'] == 'ok'
else:
assert response.json['status'] == 'degraded'

assert response.json['version']


def test_favicon(test_client):
"""
Expand Down

0 comments on commit 8468697

Please sign in to comment.