From cf1f94c327d1c33a75e82a9f8a222ce6b9811c39 Mon Sep 17 00:00:00 2001 From: Sahan Paliskara Date: Mon, 19 May 2025 17:41:52 -0700 Subject: [PATCH 1/2] add lb option to show-stats --- .github/workflows/nvidia_workflow.yml | 2 + src/discord-cluster-manager/cogs/admin_cog.py | 6 +- src/discord-cluster-manager/leaderboard_db.py | 79 +++++++++++-------- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/.github/workflows/nvidia_workflow.yml b/.github/workflows/nvidia_workflow.yml index 7852377d..5cf7c0a3 100644 --- a/.github/workflows/nvidia_workflow.yml +++ b/.github/workflows/nvidia_workflow.yml @@ -28,6 +28,8 @@ jobs: - name: Create input files shell: bash run: | + # install jq + apt update && apt install -y jq # Extract the payload content without printing it PAYLOAD=$(jq -r '.inputs.payload' $GITHUB_EVENT_PATH) diff --git a/src/discord-cluster-manager/cogs/admin_cog.py b/src/discord-cluster-manager/cogs/admin_cog.py index 8e39ee2f..179ebfb6 100644 --- a/src/discord-cluster-manager/cogs/admin_cog.py +++ b/src/discord-cluster-manager/cogs/admin_cog.py @@ -763,7 +763,9 @@ async def update_competition( @with_error_handling @discord.app_commands.describe(last_day_only="Only show stats for the last day") - async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: bool): + @discord.app_commands.describe(leaderboard_name="Name of the leaderboard") + @app_commands.autocomplete(leaderboard_name=leaderboard_name_autocomplete) + async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: bool, leaderboard_name: Optional[str] = None): is_admin = await self.admin_check(interaction) if not is_admin: await send_discord_message( @@ -774,7 +776,7 @@ async def show_bot_stats(self, interaction: discord.Interaction, last_day_only: return with self.bot.leaderboard_db as db: - stats = db.generate_stats(last_day_only) + stats = db.generate_stats(last_day_only, leaderboard_name) msg = """```""" for k, v in stats.items(): msg += f"\n{k} = {v}" diff --git a/src/discord-cluster-manager/leaderboard_db.py b/src/discord-cluster-manager/leaderboard_db.py index d48e8404..a07cf4ec 100644 --- a/src/discord-cluster-manager/leaderboard_db.py +++ b/src/discord-cluster-manager/leaderboard_db.py @@ -530,32 +530,39 @@ def get_leaderboard_submissions( for submission in self.cursor.fetchall() ] - def generate_stats(self, last_day: bool): + def generate_stats(self, last_day: bool, leaderboard_name: Optional[str] = None): try: - return self._generate_stats(last_day) + return self._generate_stats(last_day, leaderboard_name) except Exception as e: logging.exception("error generating stats", exc_info=e) raise - def _generate_runner_stats(self, last_day: bool = False): + def _generate_runner_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): select_expr = "WHERE NOW() - s.submission_time <= interval '24 hours'" if last_day else "" + leaderboard_filter = "" + if leaderboard_name: + select_expr += f" AND s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = {leaderboard_name})" + leaderboard_filter = f"JOIN leaderboard.submission s ON r.submission_id = s.id\nWHERE s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = {leaderboard_name})" + else: + select_expr += " AND NOT s.secret" # per-runner stats self.cursor.execute( - f""" - SELECT - runner, - COUNT(*), - COUNT(*) FILTER (WHERE passed), - COUNT(score), - COUNT(*) FILTER (WHERE secret), - MAX(runs.start_time - s.submission_time), - AVG(runs.start_time - s.submission_time), - SUM(runs.end_time - runs.start_time) - FROM leaderboard.runs JOIN leaderboard.submission s ON submission_id = s.id - {select_expr} - GROUP BY runner; - """ - ) + f""" + SELECT + runner, + COUNT(*), + COUNT(*) FILTER (WHERE passed), + COUNT(score), + COUNT(*) FILTER (WHERE secret), + MAX(runs.start_time - s.submission_time), + AVG(runs.start_time - s.submission_time), + SUM(runs.end_time - runs.start_time) + FROM leaderboard.runs JOIN leaderboard.submission s ON submission_id = s.id + {leaderboard_filter} + {select_expr} + GROUP BY runner; + """ + ) result = {} for row in self.cursor.fetchall(): @@ -569,19 +576,25 @@ def _generate_runner_stats(self, last_day: bool = False): return result - def _generate_submission_stats(self, last_day: bool = False): + def _generate_submission_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): select_expr = "WHERE NOW() - submission_time <= interval '24 hours'" if last_day else "" - self.cursor.execute( - f""" - SELECT - COUNT(*), - COUNT(*) FILTER (WHERE NOT done), - COUNT(DISTINCT user_id) - FROM leaderboard.submission - {select_expr} - ; - """ - ) + leaderboard_filter = "" + if leaderboard_name: + leaderboard_filter = "WHERE s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = %s)" + if not leaderboard_name: + self.cursor.execute( + f""" + SELECT + COUNT(*), + COUNT(*) FILTER (WHERE NOT done), + COUNT(DISTINCT user_id) + FROM leaderboard.submission + {leaderboard_filter} + {select_expr} + ; + """, + (leaderboard_name,) if leaderboard_name else None, + ) num_sub, num_sub_wait, num_users = self.cursor.fetchone() return { "num_submissions": num_sub, @@ -589,9 +602,9 @@ def _generate_submission_stats(self, last_day: bool = False): "num_users": num_users, } - def _generate_stats(self, last_day: bool = False): - result = self._generate_submission_stats(last_day) - result.update(self._generate_runner_stats(last_day)) + def _generate_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): + result = self._generate_submission_stats(last_day, leaderboard_name) + result.update(self._generate_runner_stats(last_day, leaderboard_name)) # code-level stats if not last_day: From 5387e8508ecf47d1fcfb9efe8504776e7b27f019 Mon Sep 17 00:00:00 2001 From: Sahan Paliskara Date: Thu, 22 May 2025 10:43:50 -0700 Subject: [PATCH 2/2] add lb option without baseline --- src/discord-cluster-manager/leaderboard_db.py | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/discord-cluster-manager/leaderboard_db.py b/src/discord-cluster-manager/leaderboard_db.py index a07cf4ec..bd695993 100644 --- a/src/discord-cluster-manager/leaderboard_db.py +++ b/src/discord-cluster-manager/leaderboard_db.py @@ -539,12 +539,10 @@ def generate_stats(self, last_day: bool, leaderboard_name: Optional[str] = None) def _generate_runner_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): select_expr = "WHERE NOW() - s.submission_time <= interval '24 hours'" if last_day else "" - leaderboard_filter = "" if leaderboard_name: - select_expr += f" AND s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = {leaderboard_name})" - leaderboard_filter = f"JOIN leaderboard.submission s ON r.submission_id = s.id\nWHERE s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = {leaderboard_name})" - else: - select_expr += " AND NOT s.secret" + select_expr += f"AND s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = '{leaderboard_name}')" + if not last_day: + select_expr = select_expr.replace("AND", "WHERE") # per-runner stats self.cursor.execute( f""" @@ -558,7 +556,6 @@ def _generate_runner_stats(self, last_day: bool = False, leaderboard_name: Optio AVG(runs.start_time - s.submission_time), SUM(runs.end_time - runs.start_time) FROM leaderboard.runs JOIN leaderboard.submission s ON submission_id = s.id - {leaderboard_filter} {select_expr} GROUP BY runner; """ @@ -577,23 +574,23 @@ def _generate_runner_stats(self, last_day: bool = False, leaderboard_name: Optio return result def _generate_submission_stats(self, last_day: bool = False, leaderboard_name: Optional[str] = None): - select_expr = "WHERE NOW() - submission_time <= interval '24 hours'" if last_day else "" + select_expr = "WHERE NOW() - s.submission_time <= interval '24 hours'" if last_day else "" leaderboard_filter = "" if leaderboard_name: - leaderboard_filter = "WHERE s.leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = %s)" - if not leaderboard_name: - self.cursor.execute( + leaderboard_filter = f"WHERE leaderboard_id = (SELECT id FROM leaderboard.leaderboard WHERE name = '{leaderboard_name}')" + if last_day: + leaderboard_filter = leaderboard_filter.replace("WHERE", "AND", 1) + select_expr += leaderboard_filter + self.cursor.execute( f""" SELECT COUNT(*), COUNT(*) FILTER (WHERE NOT done), COUNT(DISTINCT user_id) - FROM leaderboard.submission - {leaderboard_filter} + FROM leaderboard.submission s {select_expr} ; """, - (leaderboard_name,) if leaderboard_name else None, ) num_sub, num_sub_wait, num_users = self.cursor.fetchone() return { @@ -608,24 +605,39 @@ def _generate_stats(self, last_day: bool = False, leaderboard_name: Optional[str # code-level stats if not last_day: - self.cursor.execute( + leaderboard_filter = "" + if leaderboard_name: + leaderboard_filter = f""" + WHERE id IN ( + SELECT code_id FROM leaderboard.submission s + JOIN leaderboard.leaderboard l ON s.leaderboard_id = l.id + WHERE l.name = '{leaderboard_name}' + ) """ - SELECT COUNT(*) FROM leaderboard.code_files; + self.cursor.execute( + f""" + SELECT COUNT(*) FROM leaderboard.code_files + {leaderboard_filter}; """ ) result["num_unique_codes"] = self.cursor.fetchone()[0] else: # calculate heavy hitters + leaderboard_filter = "" + if leaderboard_name: + leaderboard_filter = f"AND l.name = '{leaderboard_name}'" self.cursor.execute( - """ + f""" WITH run_durations AS ( SELECT s.user_id AS user_id, r.end_time - r.start_time AS duration FROM leaderboard.runs r JOIN leaderboard.submission s ON r.submission_id = s.id + JOIN leaderboard.leaderboard l ON s.leaderboard_id = l.id WHERE NOW() - s.submission_time <= interval '24 hours' + {leaderboard_filter} ) SELECT user_id,