Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add FlareCleanupTask #947

Merged
merged 5 commits into from
Jan 6, 2025
Merged

add FlareCleanupTask #947

merged 5 commits into from
Jan 6, 2025

Conversation

nora-codecov
Copy link
Contributor

New strategy for managing flare storage

depends on codecov/shared#450

When a pull is no longer OPEN, leave the flare in order to reduce locks and wait time.
During low traffic hours (4am UTC?), run this task to clear it out of our database and Archive storage.
So we won't pay for maintaining the flare field but also won't slow down other pull actions by checking or clearing the field 🎉

@nora-codecov nora-codecov requested a review from Swatinem December 6, 2024 07:36
Copy link

github-actions bot commented Dec 6, 2024

This PR includes changes to shared. Please review them here: codecov/shared@45252f7...9f5c4fd

@nora-codecov nora-codecov requested a review from a team December 6, 2024 07:36
Copy link

codecov bot commented Dec 6, 2024

Codecov Report

Attention: Patch coverage is 96.02273% with 7 lines in your changes missing coverage. Please review.

Project coverage is 90.63%. Comparing base (1c06547) to head (20ccfb7).
Report is 1 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
database/models/core.py 55.55% 4 Missing ⚠️
tasks/flare_cleanup.py 93.87% 3 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (1c06547) and HEAD (20ccfb7). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (1c06547) HEAD (20ccfb7)
unit 2 1
integration 2 0
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #947      +/-   ##
==========================================
- Coverage   97.96%   90.63%   -7.33%     
==========================================
  Files         444      446       +2     
  Lines       35879    36045     +166     
==========================================
- Hits        35148    32671    -2477     
- Misses        731     3374    +2643     
Flag Coverage Δ
integration ?
unit 90.63% <96.02%> (+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.

⚠️ Impact Analysis from Codecov is deprecated and will be sunset on Jan 31 2025. See more

@codecov-notifications
Copy link

codecov-notifications bot commented Dec 6, 2024

Codecov Report

Attention: Patch coverage is 97.72727% with 4 lines in your changes missing coverage. Please review.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
tasks/flare_cleanup.py 93.87% 3 Missing ⚠️
database/models/core.py 88.88% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link

github-actions bot commented Dec 6, 2024

✅ All tests successful. No failed tests were found.

📣 Thoughts on this report? Let Codecov know! | Powered by Codecov

Copy link
Contributor

@Swatinem Swatinem left a comment

Choose a reason for hiding this comment

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

A couple of suggestions:

  • We should definitely limit / batch the query. This could yield millions of entries on the first run for all we know 🤷🏻‍♂️
  • Using the mock_storage fixture, you could assert the actual side effect of files being removed from the storage backend, instead of manually mocking very specific ArchiveService methods

Otherwise this looks good, and the following are just "personal preference" suggestions:

  • IMO, we should move core business logic out of the celery framework code. In this case this would mean having some free functions instead of all the logic being in FlareCleanupTask.run_cron_task. This means you don’t even need the db_session argument, as the code does not use sqlalchemy models, and it should make testing less awkward.
  • I’m personally not a fan of asserting log calls, but rather just the side effects we are aiming for: files being removed from storage, fields being cleared from the DB.

tasks/flare_cleanup.py Outdated Show resolved Hide resolved
tasks/flare_cleanup.py Outdated Show resolved Hide resolved
tasks/flare_cleanup.py Outdated Show resolved Hide resolved
tasks/tests/unit/test_flare_cleanup.py Outdated Show resolved Hide resolved
Copy link

github-actions bot commented Dec 28, 2024

This PR includes changes to shared. Please review them here: codecov/shared@2674ae9...2331c4a

@codecov-qa
Copy link

codecov-qa bot commented Dec 28, 2024

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1769 1 1768 1
View the top 1 failed tests by shortest run time
tasks/tests/unit/test_flare_cleanup.py::TestFlareCleanupTask::test_successful_run
Stack Traces | 0.309s run time
self = <worker.tasks.tests.unit.test_flare_cleanup.TestFlareCleanupTask object at 0x7f4e421ca210>
transactional_db = None
mocker = <pytest_mock.plugin.MockFixture object at 0x7f4e3be52510>

    def test_successful_run(self, transactional_db, mocker):
        mock_logs = mocker.patch("logging.Logger.info")
        mock_archive_service = mocker.patch(
            "shared.django_apps.utils.model_utils.ArchiveService"
        )
        archive_value_for_flare = {"some": "data"}
        mock_archive_service.return_value.read_file.return_value = json.dumps(
            archive_value_for_flare
        )
        mock_path = ".../to/written/object"
        mock_archive_service.return_value.write_json_data_to_storage.return_value = (
            mock_path
        )
        mock_archive_service_in_task = mocker.patch(
            "tasks.flare_cleanup.ArchiveService"
        )
        mock_archive_service_in_task.return_value.delete_file.return_value = None
    
        local_value_for_flare = {"test": "test"}
        open_pull_with_local_flare = PullFactory(
            state=PullStates.OPEN.value,
            _flare=local_value_for_flare,
            repository=RepositoryFactory(),
        )
>       assert open_pull_with_local_flare.flare == local_value_for_flare
E       AssertionError: assert {} == {'test': 'test'}
E         
E         Right contains 1 more item:
E         {'test': 'test'}
E         Use -v to get more diff

.../tests/unit/test_flare_cleanup.py:42: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

Copy link

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1769 1 1768 1
View the top 1 failed tests by shortest run time
tasks/tests/unit/test_flare_cleanup.py::TestFlareCleanupTask::test_successful_run
Stack Traces | 0.309s run time
self = <worker.tasks.tests.unit.test_flare_cleanup.TestFlareCleanupTask object at 0x7f4e421ca210>
transactional_db = None
mocker = <pytest_mock.plugin.MockFixture object at 0x7f4e3be52510>

    def test_successful_run(self, transactional_db, mocker):
        mock_logs = mocker.patch("logging.Logger.info")
        mock_archive_service = mocker.patch(
            "shared.django_apps.utils.model_utils.ArchiveService"
        )
        archive_value_for_flare = {"some": "data"}
        mock_archive_service.return_value.read_file.return_value = json.dumps(
            archive_value_for_flare
        )
        mock_path = ".../to/written/object"
        mock_archive_service.return_value.write_json_data_to_storage.return_value = (
            mock_path
        )
        mock_archive_service_in_task = mocker.patch(
            "tasks.flare_cleanup.ArchiveService"
        )
        mock_archive_service_in_task.return_value.delete_file.return_value = None
    
        local_value_for_flare = {"test": "test"}
        open_pull_with_local_flare = PullFactory(
            state=PullStates.OPEN.value,
            _flare=local_value_for_flare,
            repository=RepositoryFactory(),
        )
>       assert open_pull_with_local_flare.flare == local_value_for_flare
E       AssertionError: assert {} == {'test': 'test'}
E         
E         Right contains 1 more item:
E         {'test': 'test'}
E         Use -v to get more diff

.../tests/unit/test_flare_cleanup.py:42: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

# "kwargs": {
# "cron_task_generation_time_iso": BeatLazyFunc(get_utc_now_as_iso_format)
# },
# },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Going to test manually before I add this to the nightly cron jobs

Copy link
Contributor

@michelletran-codecov michelletran-codecov left a comment

Choose a reason for hiding this comment

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

Generally LGTM

tasks/flare_cleanup.py Show resolved Hide resolved
Copy link

github-actions bot commented Jan 6, 2025

This PR includes changes to shared. Please review them here: codecov/shared@2674ae9...efe4835

@nora-codecov nora-codecov added this pull request to the merge queue Jan 6, 2025
Merged via the queue into main with commit e1d597d Jan 6, 2025
19 of 27 checks passed
@nora-codecov nora-codecov deleted the nora/1029 branch January 6, 2025 18:52
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.

3 participants