Browse Source

Handle microseconds when scheduling (#5018)

* Handle microseconds when scheduling

* Remove pytz import.

* Happify lint.
K Davis 6 years ago
parent
commit
3ad6c6c4a7
2 changed files with 17 additions and 1 deletions
  1. 4 1
      celery/beat.py
  2. 13 0
      t/unit/app/test_beat.py

+ 4 - 1
celery/beat.py

@@ -256,7 +256,10 @@ class Scheduler(object):
     def _when(self, entry, next_time_to_run, mktime=time.mktime):
         adjust = self.adjust
 
-        return (mktime(entry.default_now().timetuple()) +
+        as_now = entry.default_now()
+                         
+        return (mktime(as_now.timetuple()) +
+                as_now.microsecond / 1e6 +
                 (adjust(next_time_to_run) or 0))
 
     def populate_heap(self, event_t=event_t, heapify=heapq.heapify):

+ 13 - 0
t/unit/app/test_beat.py

@@ -316,6 +316,19 @@ class test_Scheduler:
         scheduler.update_from_dict(s)
         assert scheduler.tick() == min(nums) - 0.010
 
+    def test_ticks_microseconds(self):
+        scheduler = mScheduler(app=self.app)
+
+        now_ts = 1514797200.2
+        now = datetime.fromtimestamp(now_ts)
+        schedule_half = schedule(timedelta(seconds=0.5), nowfun=lambda: now)
+        scheduler.add(name='half_second_schedule', schedule=schedule_half)
+
+        scheduler.tick()
+        # ensure those 0.2 seconds on now_ts don't get dropped
+        expected_time = now_ts + 0.5 - 0.010
+        assert scheduler._heap[0].time == expected_time
+
     def test_ticks_schedule_change(self):
         # initialise schedule and check heap is not initialized
         scheduler = mScheduler(app=self.app)