Skip to content

Commit 1bbb781

Browse files
committed
client-routes: include original_port in endpoint identity
1 parent 87bf16f commit 1bbb781

2 files changed

Lines changed: 53 additions & 6 deletions

File tree

cassandra/connection.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ class ClientRoutesEndPoint(EndPoint):
428428
_host_id: uuid.UUID
429429
_handler: _ClientRoutesHandler
430430
_original_address: str
431-
_original_port: int
431+
_original_port: Optional[int]
432432

433433
def __init__(self, host_id: uuid.UUID, handler: _ClientRoutesHandler, original_address: str, original_port: int = None) -> None:
434434
"""
@@ -467,15 +467,24 @@ def resolve(self) -> Tuple[str, int]:
467467

468468
def __eq__(self, other):
469469
return (isinstance(other, ClientRoutesEndPoint) and
470-
self._host_id == other._host_id and
471-
self._original_address == other._original_address)
470+
self._identity_key() == other._identity_key())
472471

473472
def __hash__(self):
474-
return hash((self._host_id, self._original_address))
473+
return hash(self._identity_key())
475474

476475
def __lt__(self, other):
477-
return ((self._host_id, self._original_address) <
478-
(other._host_id, other._original_address))
476+
return self._ordering_key() < other._ordering_key()
477+
478+
def _identity_key(self):
479+
return self._host_id, self._original_address, self._original_port
480+
481+
def _ordering_key(self):
482+
return (
483+
self._host_id,
484+
self._original_address,
485+
self._original_port is None,
486+
self._original_port,
487+
)
479488

480489
def __str__(self):
481490
return str("%s (host_id=%s)" % (self._original_address, self._host_id))

tests/unit/test_client_routes.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,44 @@ def test_resolve_falls_back_when_no_mapping(self):
433433
)
434434
self.assertEqual(ep.resolve(), ("10.0.0.1", 9042))
435435

436+
def test_original_port_is_part_of_identity(self):
437+
"""Endpoints that only differ by original port should not compare equal."""
438+
host_id = uuid.uuid4()
439+
ep_without_port = ClientRoutesEndPoint(
440+
host_id=host_id,
441+
handler=self.handler,
442+
original_address="10.0.0.1",
443+
)
444+
ep_with_port = ClientRoutesEndPoint(
445+
host_id=host_id,
446+
handler=self.handler,
447+
original_address="10.0.0.1",
448+
original_port=9042,
449+
)
450+
451+
self.assertNotEqual(ep_without_port, ep_with_port)
452+
self.assertNotEqual(hash(ep_without_port), hash(ep_with_port))
453+
454+
def test_sorting_handles_missing_original_port(self):
455+
"""Ordering should remain deterministic when original_port is None."""
456+
host_id = uuid.uuid4()
457+
ep_without_port = ClientRoutesEndPoint(
458+
host_id=host_id,
459+
handler=self.handler,
460+
original_address="10.0.0.1",
461+
)
462+
ep_with_port = ClientRoutesEndPoint(
463+
host_id=host_id,
464+
handler=self.handler,
465+
original_address="10.0.0.1",
466+
original_port=9042,
467+
)
468+
469+
self.assertEqual(
470+
sorted([ep_without_port, ep_with_port]),
471+
[ep_with_port, ep_without_port],
472+
)
473+
436474
@patch('cassandra.client_routes.socket.getaddrinfo',
437475
return_value=[(socket.AF_INET, socket.SOCK_STREAM, 0, '', ("192.168.1.100", 9042))])
438476
def test_resolve_returns_address_when_route_exists(self, _mock_getaddrinfo):

0 commit comments

Comments
 (0)