diff --git a/AUTHORS b/AUTHORS index 463b917..8e10a46 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,3 +17,4 @@ ADDITIONAL CONTRIBUTORS include: * Jaap Roes * Ed Davison * Sander Smits + * Steve Kowalik diff --git a/setup.cfg b/setup.cfg index 8257a20..0d2a4f5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,7 @@ package_dir = =src python_requires = >=3.8 install_requires = Django >= 2.2 - lockfile >= 0.8 + filelock >= 3.5 [options.packages.find] where = src diff --git a/src/mailer/engine.py b/src/mailer/engine.py index 2abe8d9..c9c3fed 100644 --- a/src/mailer/engine.py +++ b/src/mailer/engine.py @@ -4,7 +4,6 @@ import time from socket import error as socket_error -import lockfile from django import VERSION as DJANGO_VERSION from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -13,6 +12,7 @@ from django.core.mail.utils import DNS_NAME from django.db import DatabaseError, NotSupportedError, OperationalError, transaction from django.utils.module_loading import import_string +import filelock from mailer.models import RESULT_FAILURE, RESULT_SUCCESS, Message, MessageLog, get_message_id @@ -153,14 +153,15 @@ def acquire_lock(): else: lock_file_path = "send_mail" - lock = lockfile.FileLock(lock_file_path) + lock = filelock.FileLock(lock_file_path) - try: - lock.acquire(LOCK_WAIT_TIMEOUT) - except lockfile.AlreadyLocked: + if lock.is_locked: logger.error("lock already in place. quitting.") return False, lock - except lockfile.LockTimeout: + + try: + lock.acquire(timeout=LOCK_WAIT_TIMEOUT) + except filelock.Timeout: logger.error("waiting for the lock timed out. quitting.") return False, lock logger.debug("acquired.") diff --git a/tests/test_mailer.py b/tests/test_mailer.py index d6763c6..ef51cd4 100644 --- a/tests/test_mailer.py +++ b/tests/test_mailer.py @@ -4,7 +4,7 @@ from unittest.mock import Mock, PropertyMock, patch import django -import lockfile +import filelock import mailer from django.core import mail from django.core.exceptions import ImproperlyConfigured @@ -438,8 +438,10 @@ class CustomError(Exception): self.CustomError = CustomError self.lock_mock = Mock() + is_locked = PropertyMock(return_value=False) + type(self.lock_mock).is_locked = is_locked - self.patcher_lock = patch("lockfile.FileLock", return_value=self.lock_mock) + self.patcher_lock = patch("filelock.FileLock", return_value=self.lock_mock) self.patcher_prio = patch("mailer.engine.prioritize", side_effect=CustomError) self.lock = self.patcher_lock.start() @@ -447,7 +449,7 @@ class CustomError(Exception): def test(self): self.assertRaises(self.CustomError, engine.send_all) - self.lock_mock.acquire.assert_called_once_with(engine.LOCK_WAIT_TIMEOUT) + self.lock_mock.acquire.assert_called_once_with(timeout=engine.LOCK_WAIT_TIMEOUT) self.lock.assert_called_once_with("send_mail") self.prio.assert_called_once() @@ -458,12 +460,11 @@ def tearDown(self): class LockLockedTest(TestCase): def setUp(self): - config = { - "acquire.side_effect": lockfile.AlreadyLocked, - } - self.lock_mock = Mock(**config) + lock_mock = Mock() + self.is_locked = PropertyMock(return_value=True) + type(lock_mock).is_locked = self.is_locked - self.patcher_lock = patch("lockfile.FileLock", return_value=self.lock_mock) + self.patcher_lock = patch("filelock.FileLock", return_value=lock_mock) self.patcher_prio = patch("mailer.engine.prioritize", side_effect=Exception) self.lock = self.patcher_lock.start() @@ -471,8 +472,7 @@ def setUp(self): def test(self): engine.send_all() - self.lock_mock.acquire.assert_called_once_with(engine.LOCK_WAIT_TIMEOUT) - self.lock.assert_called_once_with("send_mail") + self.is_locked.assert_called_once_with() self.prio.assert_not_called() def tearDown(self): @@ -483,11 +483,13 @@ def tearDown(self): class LockTimeoutTest(TestCase): def setUp(self): config = { - "acquire.side_effect": lockfile.LockTimeout, + "acquire.side_effect": filelock.Timeout("send_mail"), } self.lock_mock = Mock(**config) + is_locked = PropertyMock(return_value=False) + type(self.lock_mock).is_locked = is_locked - self.patcher_lock = patch("lockfile.FileLock", return_value=self.lock_mock) + self.patcher_lock = patch("filelock.FileLock", return_value=self.lock_mock) self.patcher_prio = patch("mailer.engine.prioritize", side_effect=Exception) self.lock = self.patcher_lock.start() @@ -495,7 +497,7 @@ def setUp(self): def test(self): engine.send_all() - self.lock_mock.acquire.assert_called_once_with(engine.LOCK_WAIT_TIMEOUT) + self.lock_mock.acquire.assert_called_once_with(timeout=engine.LOCK_WAIT_TIMEOUT) self.lock.assert_called_once_with("send_mail") self.prio.assert_not_called() diff --git a/tox.ini b/tox.ini index 83aff4e..2dbd80d 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ envlist = py39-django{30,31,32,40}-test, py310-django{40,41,42}-test, py311-django42-test, + py312-django42-test, flake-py39-django32, checkmanifest-py39, @@ -15,6 +16,7 @@ basepython = py39: python3.9 py310: python3.10 py311: python3.11 + py312: python3.12 commands = test: pytest --cov=mailer