Description
A worker-updated discovery event whose metadata actually changed is silently ignored by WorkerProxy._worker_sentinel: the load-balancer context retains the stale WorkerMetadata (address, tags, extra, options) and its old WorkerConnection until the worker is dropped and re-added. Only no-op updates (identical metadata) pass the membership check — precisely the events that don't matter.
Expected behavior
When a worker-updated event arrives for a worker already in the pool (same uid), the context entry and its connection are refreshed with the new metadata.
Root cause
WorkerMetadata hashes by uid alone (every other field is field(hash=False), metadata.py) but the frozen dataclass __eq__ compares all fields. Dict membership is hash-bucket-then-__eq__, so the sentinel's guard event.metadata in self._loadbalancer_context.workers (proxy.py:1123) and LoadBalancerContext.update_worker's metadata in self._workers guard (loadbalancer/base.py:345) both evaluate False for any event whose metadata differs from the cached record. Fix direction: key the context by uid internally while preserving the metadata-keyed mapping surface, and make the sentinel's update path uid-based.
Description
A
worker-updateddiscovery event whose metadata actually changed is silently ignored byWorkerProxy._worker_sentinel: the load-balancer context retains the staleWorkerMetadata(address, tags, extra, options) and its oldWorkerConnectionuntil the worker is dropped and re-added. Only no-op updates (identical metadata) pass the membership check — precisely the events that don't matter.Expected behavior
When a
worker-updatedevent arrives for a worker already in the pool (same uid), the context entry and its connection are refreshed with the new metadata.Root cause
WorkerMetadatahashes byuidalone (every other field isfield(hash=False), metadata.py) but the frozen dataclass__eq__compares all fields. Dict membership is hash-bucket-then-__eq__, so the sentinel's guardevent.metadata in self._loadbalancer_context.workers(proxy.py:1123) andLoadBalancerContext.update_worker'smetadata in self._workersguard (loadbalancer/base.py:345) both evaluate False for any event whose metadata differs from the cached record. Fix direction: key the context by uid internally while preserving the metadata-keyed mapping surface, and make the sentinel's update path uid-based.