Skip to content

Commit 26bee54

Browse files
pakallisauvipy
andauthored
Handle UnpicklingError in persistent scheduler initialization (celery#9952)
* Handle UnpicklingError in persistent scheduler initialization * Update t/unit/app/test_beat.py * Fix incorrect comment referring to dbm.error instead of UnpicklingError * Fix broken tests * Fix lint offense * Dummy commit to trigger pipeline --------- Co-authored-by: Asif Saif Uddin {"Auvi":"অভি"} <[email protected]>
1 parent 7d501ca commit 26bee54

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

celery/beat.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from calendar import timegm
1313
from collections import namedtuple
1414
from functools import total_ordering
15+
from pickle import UnpicklingError
1516
from threading import Event, Thread
1617

1718
from billiard import ensure_multiprocessing
@@ -569,11 +570,11 @@ def _create_schedule(self):
569570
for _ in (1, 2):
570571
try:
571572
self._store['entries']
572-
except (KeyError, UnicodeDecodeError, TypeError):
573+
except (KeyError, UnicodeDecodeError, TypeError, UnpicklingError):
573574
# new schedule db
574575
try:
575576
self._store['entries'] = {}
576-
except (KeyError, UnicodeDecodeError, TypeError) + dbm.error as exc:
577+
except (KeyError, UnicodeDecodeError, TypeError, UnpicklingError) + dbm.error as exc:
577578
self._store = self._destroy_open_corrupted_schedule(exc)
578579
continue
579580
else:

t/unit/app/test_beat.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import dbm
22
import errno
3+
import pickle
34
import sys
45
from datetime import datetime, timedelta, timezone
56
from pickle import dumps, loads
@@ -708,6 +709,26 @@ def test_create_schedule_corrupted_dbm_error(self):
708709
s._create_schedule()
709710
s._destroy_open_corrupted_schedule.assert_called_with(expected_error)
710711

712+
def test_create_schedule_corrupted_pickle_error(self):
713+
"""
714+
Test that any UnpicklingError that might happen when opening beat-schedule.db is caught
715+
"""
716+
s = create_persistent_scheduler()[0](app=self.app,
717+
schedule_filename='schedule')
718+
s._store = MagicMock()
719+
s._destroy_open_corrupted_schedule = Mock()
720+
s._destroy_open_corrupted_schedule.return_value = MagicMock()
721+
722+
# self._store['entries'] = {} will throw a pickle.UnpicklingError
723+
s._store.__getitem__.side_effect = pickle.UnpicklingError("test")
724+
# then, when _create_schedule tries to reset _store['entries'],
725+
# throw another error, specifically pickle.UnpicklingError
726+
expected_error = pickle.UnpicklingError("test")
727+
s._store.__setitem__.side_effect = expected_error
728+
729+
s._create_schedule()
730+
s._destroy_open_corrupted_schedule.assert_called_with(expected_error)
731+
711732
def test_create_schedule_missing_entries(self):
712733
"""
713734
Test that if _create_schedule can't find the key "entries" in _store it will recreate it

0 commit comments

Comments
 (0)