-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
External versions: delete after 3 months of being merged/closed #7678
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,15 @@ | |
from django.core.files.storage import get_storage_class | ||
|
||
from readthedocs.api.v2.serializers import BuildSerializer | ||
from readthedocs.builds.constants import MAX_BUILD_COMMAND_SIZE | ||
from readthedocs.builds.constants import ( | ||
BUILD_STATUS_FAILURE, | ||
BUILD_STATUS_PENDING, | ||
BUILD_STATUS_SUCCESS, | ||
MAX_BUILD_COMMAND_SIZE, | ||
) | ||
from readthedocs.builds.models import Build, Version | ||
from readthedocs.builds.utils import memcache_lock | ||
from readthedocs.projects.tasks import send_build_status | ||
from readthedocs.worker import app | ||
|
||
log = logging.getLogger(__name__) | ||
|
@@ -163,3 +169,40 @@ def archive_builds_task(days=14, limit=200, include_cold=False, delete=False): | |
build.commands.all().delete() | ||
except IOError: | ||
log.exception('Cold Storage save failure') | ||
|
||
|
||
def delete_inactive_external_versions(limit=200, days=30 * 3): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if we really need a limit here -- are we worried about something specific with it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After 90 days, we may have a lot of versions to delete (or maybe not? We don't know how many PRs are open in a day), the task may be running for a long period of time, but not sure if that's a problem, let me know if you want me to remove it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think its fine to have a limit, I guess. We can adjust if we need to later. |
||
""" | ||
Delete external versions that have been marked as inactive after ``days``. | ||
|
||
The commit status is updated to link to the build page, as the docs are removed. | ||
""" | ||
days_ago = datetime.now() - timedelta(days=days) | ||
queryset = Version.external.filter( | ||
active=False, | ||
modified__lte=days_ago, | ||
)[:limit] | ||
for version in queryset: | ||
try: | ||
last_build = version.last_build | ||
if last_build: | ||
status = BUILD_STATUS_PENDING | ||
if last_build.finished: | ||
status = BUILD_STATUS_SUCCESS if last_build.success else BUILD_STATUS_FAILURE | ||
send_build_status( | ||
build_pk=last_build.pk, | ||
commit=last_build.commit, | ||
status=status, | ||
link_to_build=True, | ||
) | ||
except Exception: | ||
log.exception( | ||
"Failed to send status: project=%s version=%s", | ||
version.project.slug, version.slug, | ||
) | ||
else: | ||
log.info( | ||
"Removing external version. project=%s version=%s", | ||
version.project.slug, version.slug, | ||
) | ||
version.delete() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
from datetime import datetime, timedelta | ||
|
||
from django.test import TestCase | ||
from django_dynamic_fixture import get | ||
|
||
from readthedocs.builds.constants import BRANCH, EXTERNAL, TAG | ||
from readthedocs.builds.models import Version | ||
from readthedocs.builds.tasks import delete_inactive_external_versions | ||
from readthedocs.projects.models import Project | ||
|
||
|
||
class TestTasks(TestCase): | ||
|
||
def test_delete_inactive_external_versions(self): | ||
project = get(Project) | ||
project.versions.all().delete() | ||
get( | ||
Version, | ||
project=project, | ||
slug='branch', | ||
type=BRANCH, | ||
active=False, | ||
modified=datetime.now() - timedelta(days=7), | ||
) | ||
get( | ||
Version, | ||
project=project, | ||
slug='tag', | ||
type=TAG, | ||
active=True, | ||
modified=datetime.now() - timedelta(days=7), | ||
) | ||
get( | ||
Version, | ||
project=project, | ||
slug='external-active', | ||
type=EXTERNAL, | ||
active=True, | ||
modified=datetime.now() - timedelta(days=7), | ||
) | ||
get( | ||
Version, | ||
project=project, | ||
slug='external-inactive', | ||
type=EXTERNAL, | ||
active=False, | ||
modified=datetime.now() - timedelta(days=3), | ||
) | ||
get( | ||
Version, | ||
project=project, | ||
slug='external-inactive-old', | ||
type=EXTERNAL, | ||
active=False, | ||
modified=datetime.now() - timedelta(days=7), | ||
) | ||
|
||
self.assertEqual(Version.objects.all().count(), 5) | ||
self.assertEqual(Version.external.all().count(), 3) | ||
|
||
# We don't have inactive external versions from 9 days ago. | ||
delete_inactive_external_versions(days=9) | ||
self.assertEqual(Version.objects.all().count(), 5) | ||
self.assertEqual(Version.external.all().count(), 3) | ||
|
||
# We have one inactive external versions from 6 days ago. | ||
delete_inactive_external_versions(days=6) | ||
self.assertEqual(Version.objects.all().count(), 4) | ||
self.assertEqual(Version.external.all().count(), 2) | ||
self.assertFalse(Version.objects.filter(slug='external-inactive-old').exists()) |
Uh oh!
There was an error while loading. Please reload this page.