Skip to content

[Feature:System] Cleanup stale active_graders locks#12427

Merged
bmcutler merged 11 commits into
Submitty:mainfrom
srikaaviya:fix-cleanup-active-graders
Jun 23, 2026
Merged

[Feature:System] Cleanup stale active_graders locks#12427
bmcutler merged 11 commits into
Submitty:mainfrom
srikaaviya:fix-cleanup-active-graders

Conversation

@srikaaviya

@srikaaviya srikaaviya commented Feb 13, 2026

Copy link
Copy Markdown
Contributor

Why is this Change Important & Necessary?

Closes #11557

In some cases, if a grader closes their web browser with a tab open on a particular student, we will not detect that the grader is no longer actively working and the active_graders row is never cleaned up. Over time, these stale entries may accumulate and clutter the grading status dashboard.

What is the New Behavior?

Adds [sbin/cleanup_active_graders.py] — a maintenance script that:

  1. Connects to the master database to get all active courses.
  2. Iterates through each course database (submitty_{term}_{course}).
  3. Deletes active_graders rows older than 24 hours.

The script reuses the existing setup_db() helper from
[database_queries.py] to avoid duplicating database connection logic.

It is scheduled to run daily at 3AM via the Submitty cron job
([.setup/submitty_crontab].

What steps should a reviewer take to reproduce or test the bug or new feature?

  1. In a course database, manually insert a stale row into
    active_graders with a timestamp older than 48 hours.
  2. Run python3 /usr/local/submitty/sbin/cleanup_active_graders.py.
  3. Confirm the stale row is deleted and recent rows are preserved.

Automated Testing & Documentation

No automated tests added. The script logic is a straightforward
parameterized DELETE query filtered by timestamp across all course
databases.

Other information

No breaking changes or migrations. The script only performs a
targeted DELETE. The cron entry and daemon permissions are set up
as part of the standard Submitty installation process.

Closes Submitty#11557

Creates sbin/cleanup_active_graders.py that iterates through all
course databases and removes active_graders rows older than 48 hours.
These stale entries are leftover locks from graders who closed their
browser without saving.

@JManion32 JManion32 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hello @srikaaviya, thank you for your contribution, this is great work! Please be sure to follow our title guidelines (prefix and 40 chars, see more here) use the provided description template:

### Why is this Change Important & Necessary?
<!-- Include any GitHub issue that is fixed/closed using "Fixes #<number>" or "Closes #<number>" syntax.  
Alternately write "Partially addresses #<number>" or "Related to #<number>" as appropriate. -->

### What is the New Behavior?
<!-- Include before & after screenshots/videos if the user interface has changed. -->

### What steps should a reviewer take to reproduce or test the bug or new feature?

### Automated Testing & Documentation
<!-- Is this feature sufficiently tested by unit tests and end-to-end tests?  
If this PR does not add/update the necessary automated tests, write a new GitHub issue and link it below.  
Is this feature sufficiently documented on submitty.org?
Link related PRs or new GitHub issue to update documentation. -->

### Other information
<!-- Is this a breaking change?  
Does this PR include migrations to update existing installations?  
Are there security concerns with this PR? -->

Overall, the approach for this script is logical, but I do think we should reuse setup_db if possible.

Do you have a follow-up in mind for this PR that will add the script to a cron job, or installation script? You could also add it here. I'm just worried that if we merge this as-is, it may be forgotten before we can automate it.

Comment thread sbin/cleanup_active_graders.py Outdated
# 3. Construct Course DB Connection String
db_name = f"submitty_{term}_{course}"

# Logic adapted from database_queries.setup_db

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why duplicate the logic instead of reusing it here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I duplicated the connection logic because setup_db() was only connect to the 'submitty' database, and I wasn't sure if modifying an existing function was acceptable. I'll refactor setup_db() to accept an optional db_name, so it can be reused here.

@codecov

codecov Bot commented Feb 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 21.50%. Comparing base (8458ce0) to head (1f9155e).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##               main   #12427   +/-   ##
=========================================
  Coverage     21.50%   21.50%           
  Complexity     9896     9896           
=========================================
  Files           268      268           
  Lines         36968    36968           
  Branches        495      495           
=========================================
  Hits           7951     7951           
  Misses        28526    28526           
  Partials        491      491           
Flag Coverage Δ
autograder 21.32% <ø> (ø)
js 2.01% <ø> (ø)
migrator 100.00% <ø> (ø)
php 20.54% <ø> (ø)
python_submitty_utils 80.08% <ø> (ø)
submitty_daemon_jobs 91.13% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@srikaaviya

srikaaviya commented Feb 17, 2026

Copy link
Copy Markdown
Contributor Author

@JManion32 Thank you for the review! I'll update the PR title and description to follow the project guidelines, and I'll fix the CI Python lint error.

Regarding the cron job — I wasn't sure where the best place to add it would be (cron job vs installation script). Could you point me to the right file or approach? I'll include it in this PR.

I feel like adding it to the crontab would be better since we have that structure already.

@srikaaviya srikaaviya changed the title Add script to cleanup stale active_graders entries [Feature:System] Cleanup stale active_graders locks Feb 19, 2026
@srikaaviya

srikaaviya commented Mar 4, 2026

Copy link
Copy Markdown
Contributor Author

Hi @JManion32 , I've addressed all the feedback from your review (fixed the cron job placement and Python lint issues). Would you be able to take another look when you have a moment? Thanks!

@github-actions github-actions Bot added the Abandoned PR - Needs New Owner No activity on PR for more than 2 weeks -- seeking new owner to complete label Mar 18, 2026
@srikaaviya
srikaaviya requested a review from JManion32 March 18, 2026 13:19
@automateprojectmangement automateprojectmangement Bot moved this from Seeking Reviewer to In Review in Submitty Development Mar 18, 2026
@roye2
roye2 requested review from roye2 April 30, 2026 22:16

@roye2 roye2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I reviewed the code and it looks like you followed through with the changes requested by Justin. Please fix the Python linting errors.

@github-project-automation github-project-automation Bot moved this from In Review to Work in Progress in Submitty Development Apr 30, 2026
@GarvitKhandelwal31

Copy link
Copy Markdown
Contributor

@srikaaviya Python linting is still failing.

@srikaaviya

Copy link
Copy Markdown
Contributor Author

@srikaaviya Python linting is still failing.

Fixed listing errors

@dandrecollins07-ctrl dandrecollins07-ctrl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@roye2 @GarvitKhandelwal31 Pylint errors seem to have been fixed. All courses passed through the script, and cleanup_active_graders.py ran successfully across all courses in my local environment. Ready to merge.

@github-actions github-actions Bot removed the Abandoned PR - Needs New Owner No activity on PR for more than 2 weeks -- seeking new owner to complete label Jun 2, 2026
@bmcutler bmcutler moved this from Work in Progress to Awaiting Maintainer Review in Submitty Development Jun 19, 2026

@bmcutler bmcutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving now that I've properly fixed the pylint errors (we should not just comment out the lint testing if a proper fix is practical) and added a transation commit statement the PR actually works. I'm curious if the original author fully tested this PR? I'm not sure it worked before.

@bmcutler
bmcutler merged commit 1089807 into Submitty:main Jun 23, 2026
24 of 27 checks passed
@github-project-automation github-project-automation Bot moved this from Awaiting Maintainer Review to Done in Submitty Development Jun 23, 2026
@srikaaviya

Copy link
Copy Markdown
Contributor Author

Approving now that I've properly fixed the pylint errors (we should not just comment out the lint testing if a proper fix is practical) and added a transation commit statement the PR actually works. I'm curious if the original author fully tested this PR? I'm not sure it worked before.

It actually worked for me during local testing, likely because my local db was defaulting to auto-commit, so I completely missed that. Thank you for taking the time to fix and get it merged!

jndlansh pushed a commit to jndlansh/Submitty that referenced this pull request Jul 1, 2026
### Why is this Change Important & Necessary?

Closes Submitty#11557

In some cases, if a grader closes their web browser with a tab open on a
particular student, we will not detect that the grader is no longer
actively working and the `active_graders` row is never cleaned up. Over
time, these stale entries may accumulate and clutter the grading status
dashboard.

### What is the New Behavior?
Adds [sbin/cleanup_active_graders.py] — a maintenance script that:
1. Connects to the master database to get all active courses.
2. Iterates through each course database (`submitty_{term}_{course}`).
3. Deletes `active_graders` rows older than 24 hours.

The script reuses the existing `setup_db()` helper from
[database_queries.py] to avoid duplicating database connection logic.

It is scheduled to run daily at 3AM via the Submitty cron job
([.setup/submitty_crontab].

### What steps should a reviewer take to reproduce or test the bug or
new feature?
1. In a course database, manually insert a stale row into
   `active_graders` with a timestamp older than 48 hours.
2. Run `python3 /usr/local/submitty/sbin/cleanup_active_graders.py`.
3. Confirm the stale row is deleted and recent rows are preserved.

### Automated Testing & Documentation
No automated tests added. The script logic is a straightforward
parameterized DELETE query filtered by timestamp across all course
databases.

### Other information
No breaking changes or migrations. The script only performs a
targeted DELETE. The cron entry and daemon permissions are set up
as part of the standard Submitty installation process.

---------

Co-authored-by: Emma Roy <[email protected]>
Co-authored-by: Garvit Khandelwal <[email protected]>
Co-authored-by: Barb Cutler <[email protected]>
Co-authored-by: Barb Cutler <Barb Cutler>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Cleanup old active graders

6 participants