Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions misc/management/commands/cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from scoring.jobs import (
finalize_leaderboards,
update_global_comment_and_question_leaderboards,
update_gobal_bot_leaderboard,
update_custom_leaderboards,
)
from scoring.utils import update_medal_points_and_ranks
Expand Down Expand Up @@ -215,6 +216,13 @@ def handle(self, *args, **options):
max_instances=1,
replace_existing=True,
)
scheduler.add_job(
close_old_connections(update_gobal_bot_leaderboard),
trigger=CronTrigger.from_crontab("0 5 * * *"), # Every day at 05:00 UTC
id="update_gobal_bot_leaderboard",
max_instances=1,
replace_existing=True,
)
Comment on lines +219 to +225
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Scheduling conflict: both update_custom_leaderboards and update_gobal_bot_leaderboard run at 05:00 UTC.

Both jobs are scheduled at the same time (lines 207 and 214). Since update_gobal_bot_leaderboard takes ~20 minutes as noted in the PR description, running them concurrently could cause resource contention. Consider staggering the times.

♻️ Suggested fix - stagger to 06:00 UTC
         scheduler.add_job(
             close_old_connections(update_gobal_bot_leaderboard),
-            trigger=CronTrigger.from_crontab("0 5 * * *"),  # Every day at 05:00 UTC
+            trigger=CronTrigger.from_crontab("0 6 * * *"),  # Every day at 06:00 UTC
             id="update_gobal_bot_leaderboard",
             max_instances=1,
             replace_existing=True,
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
scheduler.add_job(
close_old_connections(update_gobal_bot_leaderboard),
trigger=CronTrigger.from_crontab("0 5 * * *"), # Every day at 05:00 UTC
id="update_gobal_bot_leaderboard",
max_instances=1,
replace_existing=True,
)
scheduler.add_job(
close_old_connections(update_gobal_bot_leaderboard),
trigger=CronTrigger.from_crontab("0 6 * * *"), # Every day at 06:00 UTC
id="update_gobal_bot_leaderboard",
max_instances=1,
replace_existing=True,
)
🤖 Prompt for AI Agents
In `@misc/management/commands/cron.py` around lines 212 - 218, The two scheduled
jobs update_custom_leaderboards and update_gobal_bot_leaderboard are both added
via scheduler.add_job using CronTrigger.from_crontab("0 5 * * *") and will run
concurrently; change one cron expression to a staggered time (e.g., set
update_gobal_bot_leaderboard to "0 6 * * *") so the long-running
update_gobal_bot_leaderboard does not overlap with update_custom_leaderboards,
keeping id, max_instances, replace_existing handling the same.


#
# Comment Jobs
Expand Down
17 changes: 17 additions & 0 deletions scoring/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,26 @@
from scoring.tasks import update_custom_leaderboard
from scoring.tasks import update_coherence_spring_2026_cup

from scoring.management.commands.update_global_bot_leaderboard import (
run_update_global_bot_leaderboard,
)

logger = logging.getLogger(__name__)


def update_gobal_bot_leaderboard():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo in function name: update_gobal_bot_leaderboard should be update_global_bot_leaderboard.

The function name has a typo ("gobal" vs "global"). This typo propagates to the cron job ID and import. Fix this before it becomes a maintenance headache.

♻️ Proposed fix
-def update_gobal_bot_leaderboard():
+def update_global_bot_leaderboard():

Also update the import in misc/management/commands/cron.py accordingly.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def update_gobal_bot_leaderboard():
def update_global_bot_leaderboard():
🤖 Prompt for AI Agents
In `@scoring/jobs.py` at line 19, Rename the misspelled function
update_gobal_bot_leaderboard to update_global_bot_leaderboard and update every
reference to it (including the cron job ID and any imports) so names stay
consistent; specifically change the import and usage in
misc/management/commands/cron.py to import update_global_bot_leaderboard and
update the cron registration/ID that currently uses the typo, then run a quick
search for update_gobal_bot_leaderboard to replace remaining occurrences.

global_bot_leaderboard = Leaderboard.objects.filter(
name="Global Bot Leaderboard",
).first()
if not global_bot_leaderboard:
logger.warning("Global Bot Leaderboard not found.")
return
try:
run_update_global_bot_leaderboard()
except Exception as e:
logger.error(f"Error updating Global Bot Leaderboard: {e}")
Comment on lines +20 to +30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Guard is ineffective and logger.error loses the traceback.

Two issues:

  1. The existence check on Lines 21-26 guards against a missing leaderboard, but run_update_global_bot_leaderboard() internally calls Leaderboard.objects.get_or_create(...) (line 951 of the command file), so it will create the leaderboard anyway—making this guard a no-op.
  2. Use logger.exception instead of logger.error to preserve the full traceback in logs.
Proposed fix
 def update_gobal_bot_leaderboard():
-    global_bot_leaderboard = Leaderboard.objects.filter(
-        name="Global Bot Leaderboard",
-    ).first()
-    if not global_bot_leaderboard:
-        logger.warning("Global Bot Leaderboard not found.")
-        return
     try:
         run_update_global_bot_leaderboard()
     except Exception as e:
-        logger.error(f"Error updating Global Bot Leaderboard: {e}")
+        logger.exception(f"Error updating Global Bot Leaderboard: {e}")

If the guard is intentional (i.e., the job should only run when the leaderboard already exists), remove the get_or_create from the runner and pass the leaderboard instance in, so the two call-sites agree on the contract.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def update_gobal_bot_leaderboard():
global_bot_leaderboard = Leaderboard.objects.filter(
name="Global Bot Leaderboard",
).first()
if not global_bot_leaderboard:
logger.warning("Global Bot Leaderboard not found.")
return
try:
run_update_global_bot_leaderboard()
except Exception as e:
logger.error(f"Error updating Global Bot Leaderboard: {e}")
def update_gobal_bot_leaderboard():
try:
run_update_global_bot_leaderboard()
except Exception as e:
logger.exception(f"Error updating Global Bot Leaderboard: {e}")
🧰 Tools
🪛 Ruff (0.14.14)

[warning] 29-29: Do not catch blind exception: Exception

(BLE001)


[warning] 30-30: Use logging.exception instead of logging.error

Replace with exception

(TRY400)

🤖 Prompt for AI Agents
In `@scoring/jobs.py` around lines 20 - 30, The guard in
update_gobal_bot_leaderboard is ineffective because
run_update_global_bot_leaderboard internally calls
Leaderboard.objects.get_or_create, so the pre-check is a no-op; decide one
contract and make both call sites match: either remove the existence check in
update_gobal_bot_leaderboard and let run_update_global_bot_leaderboard handle
creation, or change run_update_global_bot_leaderboard to accept a Leaderboard
instance (pass the queried global_bot_leaderboard) and remove get_or_create
there. Also replace logger.error with logger.exception in
update_gobal_bot_leaderboard to preserve the traceback when catching exceptions
from run_update_global_bot_leaderboard.



def update_global_comment_and_question_leaderboards():
global_leaderboards = Leaderboard.objects.filter(
finalized=False,
Expand Down
Loading
Loading