diff --git a/hc/api/management/commands/sendalerts.py b/hc/api/management/commands/sendalerts.py index 2577568d..7abd122c 100644 --- a/hc/api/management/commands/sendalerts.py +++ b/hc/api/management/commands/sendalerts.py @@ -35,7 +35,15 @@ class Command(BaseCommand): help='Do not keep running indefinitely in a 2 second wait loop', ) - def handle_one(self): + parser.add_argument( + '--no-threads', + action='store_false', + dest='use_threads', + default=False, + help='Send alerts synchronously, without using threads', + ) + + def handle_one(self, use_threads=True): """ Process a single check. """ now = timezone.now() @@ -65,15 +73,20 @@ class Command(BaseCommand): if num_updated == 1: # Send notifications only if status update succeeded # (no other sendalerts process got there first) - notify_on_thread(check.id, self.stdout) + if use_threads: + notify_on_thread(check.id, self.stdout) + else: + notify(check.id, self.stdout) + return True return False def handle(self, *args, **options): + use_threads = options["use_threads"] if not options["loop"]: x = 0 - while self.handle_one(): + while self.handle_one(use_threads): # returns True when there are more alerts to send. x += 1 return "Sent %d alert(s)" % x @@ -83,7 +96,7 @@ class Command(BaseCommand): ticks = 0 while True: - while self.handle_one(): + while self.handle_one(use_threads): ticks = 0 ticks += 1 diff --git a/hc/api/tests/test_sendalerts.py b/hc/api/tests/test_sendalerts.py index 5136a487..fc64bb7e 100644 --- a/hc/api/tests/test_sendalerts.py +++ b/hc/api/tests/test_sendalerts.py @@ -1,6 +1,7 @@ from datetime import timedelta from mock import patch +from django.core.management import call_command from django.utils import timezone from hc.api.management.commands.sendalerts import Command from hc.api.models import Check @@ -35,7 +36,7 @@ class SendAlertsTestCase(BaseTestCase): check.refresh_from_db() self.assertEqual(check.status, "down") - # It should call `notify` + # It should call `notify_on_thread` self.assertTrue(mock_notify.called) @patch("hc.api.management.commands.sendalerts.notify_on_thread") @@ -54,7 +55,7 @@ class SendAlertsTestCase(BaseTestCase): check.refresh_from_db() self.assertEqual(check.status, "up") - # It should call `notify` + # It should call `notify_on_thread` self.assertTrue(mock_notify.called) # alert_after now should be set @@ -78,5 +79,17 @@ class SendAlertsTestCase(BaseTestCase): # alert_after should have been increased self.assertTrue(check.alert_after > check.last_ping) - # notify should *not* have been called + # notify_on_thread should *not* have been called self.assertFalse(mock_notify.called) + + @patch("hc.api.management.commands.sendalerts.notify") + def test_it_works_synchronously(self, mock_notify): + check = Check(user=self.alice, status="up") + check.last_ping = timezone.now() - timedelta(days=2) + check.alert_after = check.get_alert_after() + check.save() + + call_command("sendalerts", loop=False, use_threads=False) + + # It should call `notify` instead of `notify_on_thread` + self.assertTrue(mock_notify.called)