WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@maxweng-sentry
Copy link
Contributor

@maxweng-sentry maxweng-sentry commented Nov 11, 2025

https://linear.app/getsentry/issue/CCMRG-1821/we-should-not-let-the-notify-task-run-if-there-are-still-pending

Checks to see if there are any uploads still pending before triggering the notify task. Also cleans up any stalled uploads so that future uploads can successfully finish.

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@sentry
Copy link

sentry bot commented Nov 12, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.87%. Comparing base (519a0a9) to head (5bdcbd7).
⚠️ Report is 26 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #558      +/-   ##
==========================================
+ Coverage   93.85%   93.87%   +0.01%     
==========================================
  Files        1284     1284              
  Lines       46428    46434       +6     
  Branches     1524     1524              
==========================================
+ Hits        43574    43588      +14     
+ Misses       2545     2537       -8     
  Partials      309      309              
Flag Coverage Δ
workerintegration 58.60% <66.66%> (+0.02%) ⬆️
workerunit 91.21% <100.00%> (+0.03%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@codecov-notifications
Copy link

codecov-notifications bot commented Nov 12, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

state = ProcessingState(repoid, commitid)
upload_numbers = state.get_upload_numbers()

if upload_numbers.processing > 0 or upload_numbers.processed > 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

processed to me implies that it's "done," e.g. a processing upload turns to a processed one. Is that not the case?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, this is true, but there's another state merged.

Copy link
Contributor

Choose a reason for hiding this comment

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

To add to this, I think we should have a helper function in state.py that does this logic. Perhaps has_unmerged_uploads

except SoftTimeLimitExceeded:
log.warning("run_impl: soft time limit exceeded")
# Clean up orphaned state so future finishers can proceed
state.mark_uploads_as_merged(upload_ids)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is wrong, this will mark all uploads as merged correct? But if we hit a SoftTimeLimitExceeded, I'm guessing this is not true

state = ProcessingState(repoid, commitid)
upload_numbers = state.get_upload_numbers()

if upload_numbers.processing > 0 or upload_numbers.processed > 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, this is true, but there's another state merged.

assert result == []

@pytest.mark.django_db
def test_upload_finisher_updates_repository_timestamp(
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this test need to exist as a standalone?

state = ProcessingState(repoid, commitid)
upload_numbers = state.get_upload_numbers()

if upload_numbers.processing > 0 or upload_numbers.processed > 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

To add to this, I think we should have a helper function in state.py that does this logic. Perhaps has_unmerged_uploads

log.info(
"Retrying ManualTriggerTask. Redis shows uploads still being processed.",
extra={
"repoid": repoid,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: alphabetize

if not upload.state or upload.state_id == UploadState.UPLOADED.db_id:
still_processing += 1

# Also check Redis processing state to prevent race conditions
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I buy this, I think it makes more sense to use either the DB or Redis as the source of truth even with a race condition.

"commitid": commitid,
"redis_processing": upload_numbers.processing,
"redis_processed": upload_numbers.processed,
"db_still_processing": still_processing,
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure the value this will have if it doesn't equal redis_processing + redis_processed

@codecov-eu
Copy link

codecov-eu bot commented Nov 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!


# Check if there are still pending uploads in the database
# Use DB as source of truth for upload completion status
if db_session:
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this should be a helper function as we call it twice

@maxweng-sentry maxweng-sentry added this pull request to the merge queue Nov 20, 2025
Merged via the queue into main with commit 5ae548a Nov 20, 2025
39 checks passed
@maxweng-sentry maxweng-sentry deleted the max/notify-fix branch November 20, 2025 18:30
@armenzg
Copy link

armenzg commented Dec 3, 2025

@sentry review

Comment on lines +323 to +326
# Use DB as source of truth - if any uploads are still in UPLOADED state,
# another finisher will process them and we shouldn't send notifications yet
remaining_uploads = (
db_session.query(Upload)
Copy link

Choose a reason for hiding this comment

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

The SQLAlchemy filter Upload.report.has(commit=commit) is less explicit than directly referencing the CommitReport model's relationship to Commit. For clarity and robustness, consider changing this to Upload.report.has(CommitReport.commit == commit) or Upload.report.has(CommitReport.commit_id == commit.id_), similar to how CommitReport.commit == commit is used in manual_trigger.py.
Severity: MEDIUM

🤖 Prompt for AI Agent

Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: apps/worker/tasks/upload_finisher.py#L323-L326

Potential issue: The SQLAlchemy filter `Upload.report.has(commit=commit)` is less
explicit than directly referencing the `CommitReport` model's relationship to `Commit`.
For clarity and robustness, consider changing this to
`Upload.report.has(CommitReport.commit == commit)` or
`Upload.report.has(CommitReport.commit_id == commit.id_)`, similar to how
`CommitReport.commit == commit` is used in `manual_trigger.py`.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 5283190

Comment on lines 685 to 672
processing_results: list[ProcessingResult],
db_session=None,
) -> ShouldCallNotifyResult:
extra_dict = {
"repoid": commit.repoid,
Copy link

Choose a reason for hiding this comment

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

Similar to the query in run_impl, the SQLAlchemy filter Upload.report.has(commit=commit) could be made more explicit. Using Upload.report.has(CommitReport.commit == commit) or Upload.report.has(CommitReport.commit_id == commit.id_) would improve readability and maintainability, aligning with more standard SQLAlchemy practices.
Severity: MEDIUM

🤖 Prompt for AI Agent

Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: apps/worker/tasks/upload_finisher.py#L669-L672

Potential issue: Similar to the query in `run_impl`, the SQLAlchemy filter
`Upload.report.has(commit=commit)` could be made more explicit. Using
`Upload.report.has(CommitReport.commit == commit)` or
`Upload.report.has(CommitReport.commit_id == commit.id_)` would improve readability and
maintainability, aligning with more standard SQLAlchemy practices.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 5283190

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants