summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/apscheduler/datastores/memory.py4
-rw-r--r--tests/test_datastores.py17
2 files changed, 20 insertions, 1 deletions
diff --git a/src/apscheduler/datastores/memory.py b/src/apscheduler/datastores/memory.py
index 65fad9e..7014bf1 100644
--- a/src/apscheduler/datastores/memory.py
+++ b/src/apscheduler/datastores/memory.py
@@ -50,8 +50,10 @@ class ScheduleState:
return False
elif other.next_fire_time is None:
return self.next_fire_time is not None
- else:
+ elif self.next_fire_time != other.next_fire_time:
return self.next_fire_time < other.next_fire_time
+ else:
+ return self.schedule.id < other.schedule.id
def __hash__(self):
return hash(self.schedule.id)
diff --git a/tests/test_datastores.py b/tests/test_datastores.py
index 0b484f1..02efc08 100644
--- a/tests/test_datastores.py
+++ b/tests/test_datastores.py
@@ -304,6 +304,23 @@ class TestAsyncStores:
assert not events
+ async def test_release_schedule_two_identical_fire_times(self, datastore: AsyncDataStore) -> None:
+ """Regression test for #616."""
+ async with datastore:
+ for i in range(1, 3):
+ trigger = DateTrigger(datetime(2020, 9, 13, tzinfo=timezone.utc))
+ schedule = Schedule(id=f's{i}', task_id='task1', trigger=trigger)
+ schedule.next_fire_time = trigger.next()
+ await datastore.add_schedule(schedule, ConflictPolicy.exception)
+
+ schedules = await datastore.acquire_schedules('foo', 3)
+ schedules[0].next_fire_time = None
+ await datastore.release_schedules('foo', schedules)
+
+ remaining = await datastore.get_schedules({s.id for s in schedules})
+ assert len(remaining) == 1
+ assert remaining[0].id == schedules[1].id
+
async def test_acquire_schedules_lock_timeout(
self, datastore: AsyncDataStore, schedules: list[Schedule], freezer) -> None:
"""