diff --git a/hippolyzer/lib/proxy/objects.py b/hippolyzer/lib/proxy/objects.py index 1140284..226adcf 100644 --- a/hippolyzer/lib/proxy/objects.py +++ b/hippolyzer/lib/proxy/objects.py @@ -484,12 +484,10 @@ class ObjectManager: update_futures = self._update_futures[obj.LocalID] for fut in update_futures[:]: fut.set_result(obj) - update_futures.remove(fut) elif update_type == UpdateType.PROPERTIES: property_futures = self._property_futures[obj.LocalID] for fut in property_futures[:]: fut.set_result(obj) - property_futures.remove(fut) AddonManager.handle_object_updated(self._region.session(), self._region, obj, updated_props) def load_cache(self): @@ -549,7 +547,9 @@ class ObjectManager: fut = asyncio.Future() if local_id in unselected_ids: # Need to wait until we get our reply - self._property_futures[local_id].append(fut) + local_futs = self._property_futures[local_id] + local_futs.append(fut) + fut.add_done_callback(local_futs.remove) else: # This was selected so we should already have up to date info fut.set_result(self.lookup_localid(local_id)) @@ -583,6 +583,8 @@ class ObjectManager: futures = [] for local_id in local_ids: fut = asyncio.Future() - self._update_futures[local_id].append(fut) + local_futs = self._update_futures[local_id] + local_futs.append(fut) + fut.add_done_callback(local_futs.remove) futures.append(fut) return futures diff --git a/tests/proxy/test_object_manager.py b/tests/proxy/test_object_manager.py index 3a22861..c9e8fb9 100644 --- a/tests/proxy/test_object_manager.py +++ b/tests/proxy/test_object_manager.py @@ -444,8 +444,8 @@ class ObjectManagerTests(ObjectManagerTestMixin, unittest.TestCase): class AsyncObjectManagerTests(ObjectManagerTestMixin, unittest.IsolatedAsyncioTestCase): async def test_request_objects(self): - # request three objects, one of which won't receive an ObjectUpdate - futures = self.object_manager.request_objects((1234, 1235, 1236)) + # request four objects, two of which won't receive an ObjectUpdate + futures = self.object_manager.request_objects((1234, 1235, 1236, 1237)) self._create_object(1234) self._create_object(1235) done, pending = await asyncio.wait(futures, timeout=0.0001) @@ -453,11 +453,18 @@ class AsyncObjectManagerTests(ObjectManagerTestMixin, unittest.IsolatedAsyncioTe # wait() returns unordered results, so use a set. self.assertEqual(set(o.LocalID for o in objects), {1234, 1235}) pending = list(pending) - self.assertEqual(len(pending), 1) + self.assertEqual(2, len(pending)) # The other futures being resolved should have removed them from the dict pending_futures = sum(len(x) for x in self.object_manager._update_futures.values()) - self.assertEqual(pending_futures, 1) + self.assertEqual(2, pending_futures) + pending_1, pending_2 = pending - self.assertFalse(pending[0].cancelled()) + # Timing out should cancel + with self.assertRaises(asyncio.TimeoutError): + await asyncio.wait_for(pending_1, 0.00001) + self.assertTrue(pending_1.cancelled()) + + # Object manager being cleared due to region death should cancel + self.assertFalse(pending_2.cancelled()) self.object_manager.clear() - self.assertTrue(pending[0].cancelled()) + self.assertTrue(pending_2.cancelled())