perf: stabilize the model registry signature across workers (#29264)

The Redis-backed model registry skips its write when the content signature matches what is already stored. That skip has never worked across processes. Two of the values it hashes come out of Python sets, and set iteration order varies with each process's hash seed, so every worker computed a different signature for identical content and every worker rewrote the whole registry on every refresh.

Sorting both makes the signature depend on content alone. Measured on a 120 model registry, 522 KiB serialized: a refresh whose content already matches drops from GET, HKEYS, HSET and SET at 5.1 ms to a single GET at 2.2 ms per worker, and the 522 KiB write leaves the wire entirely.

Verified across 12 child processes with 12 distinct hash seeds: 12 different signatures before, 1 after. Filter execution order is unaffected, because the filter pipeline re-sorts by priority and id before running.
This commit is contained in:
Classic298 2026-08-30 22:12:31 +02:00 committed by GitHub
parent cfa2d25317
commit b8f279b8fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 3 additions and 1 deletions

View file

@ -112,7 +112,7 @@ def _safe_field(key: str, definition: dict[str, Any]) -> dict[str, Any]:
'type',
}
field = {'key': key}
for field_key in allowed_keys:
for field_key in sorted(allowed_keys):
if field_key in definition:
field[field_key] = definition[field_key]

View file

@ -374,6 +374,8 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None)
for filter_id in set(model.pop('filter_ids', [])) | global_filter_ids
if filter_id in enabled_filter_ids
]
# Set order varies per process, and an unstable order defeats the RedisDict content signature.
filter_ids.sort()
model['actions'] = []
for action_id in action_ids: