Merge pull request #182 from malmeloo:feat/key-alignment

feat: improve key alignment efficiency
This commit is contained in:
Mike Almeloo
2025-09-24 23:05:38 +02:00
committed by GitHub
2 changed files with 16 additions and 11 deletions

View File

@@ -61,9 +61,11 @@ class RollingKeyPairSource(ABC):
@abstractmethod
def update_alignment(self, dt: datetime, index: int) -> None:
"""
Update alignment of the accessory.
Update alignment of the accessory based on a key index that was observed at a specific time.
Alignment can be updated based on a LocationReport that was observed at a specific index.
Implementations of this method should consider that this method may be called
multiple times, sometimes with seemingly conflicting data: the same index may be
observed at different times, or multiple indices may be observed at the same time.
"""
raise NotImplementedError
@@ -222,8 +224,13 @@ class FindMyAccessory(RollingKeyPairSource, util.abc.Serializable[FindMyAccessor
@override
def update_alignment(self, dt: datetime, index: int) -> None:
if dt < self._alignment_date:
# we only care about the most recent report
if dt < self._alignment_date or index < self._alignment_index:
# We only care about the most recent report and index.
# Multiple calls to this method may be made with
# possibly conflicting data, so we just ignore
# anything that seems to go backwards in time or index.
# Saving the newest data is at least likely to be stable
# over multiple fetches.
return
logger.info("Updating alignment based on report observed at index %i", index)

View File

@@ -431,7 +431,7 @@ class LocationReportsFetcher:
# state variables
cur_keys_primary: set[str] = set()
cur_keys_secondary: set[str] = set()
cur_index = accessory.get_min_index(start_date)
cur_index = accessory.get_max_index(start_date)
ret: set[LocationReport] = set()
async def _fetch() -> set[LocationReport]:
@@ -446,17 +446,15 @@ class LocationReportsFetcher:
report.decrypt(key)
# update alignment data on every report
# if a key maps to multiple indices, only feed it the maximum index,
# since apple only returns the latest reports per request.
# This makes the value more likely to be stable.
accessory.update_alignment(report.timestamp, max(key_to_ind[key]))
for i in key_to_ind[key]:
accessory.update_alignment(report.timestamp, i)
cur_keys_primary.clear()
cur_keys_secondary.clear()
return set(new_reports)
while cur_index <= accessory.get_max_index(end_date):
while cur_index >= accessory.get_min_index(end_date):
key_batch = accessory.keys_at(cur_index)
# split into primary and secondary keys
@@ -483,7 +481,7 @@ class LocationReportsFetcher:
cur_keys_primary |= new_keys_primary
cur_keys_secondary |= new_keys_secondary
cur_index += 1
cur_index -= 1
if cur_keys_primary or cur_keys_secondary:
# fetch remaining keys