From aecd9f67db22b1901f82875c690213230ff36994 Mon Sep 17 00:00:00 2001
From: Antonis Christofides <antonis@antonischristofides.com>
Date: Sun, 17 Nov 2024 10:48:23 +0200
Subject: [PATCH] Fix a race condition when fetching telemetry data (fixes
 DEV-37)

---
 enhydris/telemetry/tasks.py            | 5 ++++-
 enhydris/telemetry/tests/test_tasks.py | 8 ++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/enhydris/telemetry/tasks.py b/enhydris/telemetry/tasks.py
index ccc0decb..71a16c06 100644
--- a/enhydris/telemetry/tasks.py
+++ b/enhydris/telemetry/tasks.py
@@ -20,7 +20,10 @@ def fetch_all_telemetry_data():
 
 @app.task(bind=True, soft_time_limit=FETCH_TIMEOUT, time_limit=FETCH_TIMEOUT + 10)
 def fetch_telemetry_data(self, telemetry_id):
-    telemetry = Telemetry.objects.get(id=telemetry_id)
+    try:
+        telemetry = Telemetry.objects.get(id=telemetry_id)
+    except Telemetry.DoesNotExist:
+        return
     lock_id = f"telemetry-{telemetry_id}"
     acquired_lock = cache.add(lock_id, self.app.oid, LOCK_TIMEOUT)
     if acquired_lock:
diff --git a/enhydris/telemetry/tests/test_tasks.py b/enhydris/telemetry/tests/test_tasks.py
index f99ce82b..0aceb1b9 100644
--- a/enhydris/telemetry/tests/test_tasks.py
+++ b/enhydris/telemetry/tests/test_tasks.py
@@ -49,6 +49,14 @@ def test_logs_error_if_locked(self, mock_logger, mock_fetch, mock_cache):
         tasks.fetch_telemetry_data(self.telemetry.id)
         mock_logger.error.assert_called_once()
 
+    def test_deleted_telemetry(self, mock_fetch, mock_cache):
+        # Sometimes a telemetry may get deleted between queuing the fetching of
+        # data and actually starting executing it. We test that in that case there's
+        # no exception and the fetching is merely ignored.
+        telemetry_id = self.telemetry.id
+        self.telemetry.delete()
+        tasks.fetch_telemetry_data(telemetry_id)  # Should not raise exception
+
 
 @patch("enhydris.telemetry.tasks.fetch_telemetry_data.delay")
 class FetchAllTelemetryDataTestCase(TestCase):