Skip to content

Commit 1a2996e

Browse files
feat: expire submissions after 14 days (ietf-tools#7461)
* feat: expire submissions after 14 days * test: update test_cancel_stale_submissions
1 parent a1a3097 commit 1a2996e

3 files changed

Lines changed: 59 additions & 10 deletions

File tree

ietf/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,9 @@ def skip_unreadable_post(record):
817817
# Max time to allow for validation before a submission is subject to cancellation
818818
IDSUBMIT_MAX_VALIDATION_TIME = datetime.timedelta(minutes=20)
819819

820+
# Age at which a submission expires if not posted
821+
IDSUBMIT_EXPIRATION_AGE = datetime.timedelta(days=14)
822+
820823
IDSUBMIT_MANUAL_STAGING_DIR = '/tmp/'
821824

822825
IDSUBMIT_FILE_TYPES = (

ietf/submit/tasks.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,34 @@ def process_and_accept_uploaded_submission_task(submission_id):
3737
@shared_task
3838
def cancel_stale_submissions():
3939
now = timezone.now()
40-
stale_submissions = Submission.objects.filter(
40+
# first check for submissions gone stale awaiting validation
41+
stale_unvalidated_submissions = Submission.objects.filter(
4142
state_id='validating',
4243
).annotate(
4344
submitted_at=Min('submissionevent__time'),
4445
).filter(
4546
submitted_at__lt=now - settings.IDSUBMIT_MAX_VALIDATION_TIME,
4647
)
47-
for subm in stale_submissions:
48+
for subm in stale_unvalidated_submissions:
4849
age = now - subm.submitted_at
4950
log.log(f'Canceling stale submission (id={subm.id}, age={age})')
5051
cancel_submission(subm)
5152
create_submission_event(None, subm, 'Submission canceled: validation checks took too long')
5253

54+
# now check for expired submissions
55+
expired_submissions = Submission.objects.exclude(
56+
state_id__in=["posted", "cancel"],
57+
).annotate(
58+
submitted_at=Min("submissionevent__time"),
59+
).filter(
60+
submitted_at__lt=now - settings.IDSUBMIT_EXPIRATION_AGE,
61+
)
62+
for subm in expired_submissions:
63+
age = now - subm.submitted_at
64+
log.log(f'Canceling expired submission (id={subm.id}, age={age})')
65+
cancel_submission(subm)
66+
create_submission_event(None, subm, 'Submission canceled: expired without being posted')
67+
5368

5469
@shared_task(bind=True)
5570
def poke(self):

ietf/submit/tests.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
from ietf.group.utils import setup_default_community_list_for_group
4343
from ietf.meeting.models import Meeting
4444
from ietf.meeting.factories import MeetingFactory
45-
from ietf.name.models import FormalLanguageName
45+
from ietf.name.models import DraftSubmissionStateName, FormalLanguageName
4646
from ietf.person.models import Person
4747
from ietf.person.factories import UserFactory, PersonFactory, EmailFactory
4848
from ietf.submit.factories import SubmissionFactory, SubmissionExtResourceFactory
@@ -3136,28 +3136,59 @@ def test_status_of_validating_submission(self):
31363136
self.assertContains(r, s.name)
31373137
self.assertContains(r, 'This submission is being processed and validated.', status_code=200)
31383138

3139-
@override_settings(IDSUBMIT_MAX_VALIDATION_TIME=datetime.timedelta(minutes=30))
3139+
@override_settings(
3140+
IDSUBMIT_MAX_VALIDATION_TIME=datetime.timedelta(minutes=30),
3141+
IDSUBMIT_EXPIRATION_AGE=datetime.timedelta(minutes=90),
3142+
)
31403143
def test_cancel_stale_submissions(self):
3144+
# these will be lists of (Submission, "state_id") pairs
3145+
submissions_to_skip = []
3146+
submissions_to_cancel = []
3147+
3148+
# submissions in the validating state
31413149
fresh_submission = SubmissionFactory(state_id='validating')
31423150
fresh_submission.submissionevent_set.create(
31433151
desc='fake created event',
31443152
time=timezone.now() - datetime.timedelta(minutes=15),
31453153
)
3154+
submissions_to_skip.append((fresh_submission, "validating"))
3155+
31463156
stale_submission = SubmissionFactory(state_id='validating')
31473157
stale_submission.submissionevent_set.create(
31483158
desc='fake created event',
31493159
time=timezone.now() - datetime.timedelta(minutes=30, seconds=1),
31503160
)
3161+
submissions_to_cancel.append((stale_submission, "validating"))
3162+
3163+
# submissions in other states
3164+
for state in DraftSubmissionStateName.objects.filter(used=True).exclude(slug="validating"):
3165+
to_skip = SubmissionFactory(state_id=state.pk)
3166+
to_skip.submissionevent_set.create(
3167+
desc="fake created event",
3168+
time=timezone.now() - datetime.timedelta(minutes=45), # would be canceled if it were "validating"
3169+
)
3170+
submissions_to_skip.append((to_skip, state.pk))
3171+
to_expire = SubmissionFactory(state_id=state.pk)
3172+
to_expire.submissionevent_set.create(
3173+
desc="fake created event",
3174+
time=timezone.now() - datetime.timedelta(minutes=90, seconds=1),
3175+
)
3176+
if state.pk in ["posted", "cancel"]:
3177+
submissions_to_skip.append((to_expire, state.pk)) # these ones should not be expired regardless of age
3178+
else:
3179+
submissions_to_cancel.append(((to_expire, state.pk)))
31513180

31523181
cancel_stale_submissions()
31533182

3154-
fresh_submission = Submission.objects.get(pk=fresh_submission.pk)
3155-
self.assertEqual(fresh_submission.state_id, 'validating')
3156-
self.assertEqual(fresh_submission.submissionevent_set.count(), 1)
3183+
for _subm, original_state_id in submissions_to_skip:
3184+
subm = Submission.objects.get(pk=_subm.pk)
3185+
self.assertEqual(subm.state_id, original_state_id)
3186+
self.assertEqual(subm.submissionevent_set.count(), 1)
31573187

3158-
stale_submission = Submission.objects.get(pk=stale_submission.pk)
3159-
self.assertEqual(stale_submission.state_id, 'cancel')
3160-
self.assertEqual(stale_submission.submissionevent_set.count(), 2)
3188+
for _subm, _ in submissions_to_cancel:
3189+
subm = Submission.objects.get(pk=_subm.pk)
3190+
self.assertEqual(subm.state_id, "cancel")
3191+
self.assertEqual(subm.submissionevent_set.count(), 2)
31613192

31623193

31633194
class ApiSubmitTests(BaseSubmitTestCase):

0 commit comments

Comments
 (0)