Skip to content

Commit fb3e24c

Browse files
authored
fix(worker): Send a portless :authority from the push client (#795)
grpc puts the whole host:port target in :authority, so a push worker dialing task-<pool>-broker-grpc:50051 through the mesh matches no route -- HttpRoute hostnames are RFC1123 names and cannot carry a port -- and envoy's 404 comes back as UNIMPLEMENTED. Setting grpc.default_authority to the target without its port makes the worker look like the broker, which reaches its worker over a portless URL and has always matched.
1 parent 6471999 commit fb3e24c

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

‎clients/python/src/taskbroker_client/worker/push_clients.py‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@
2727
logger = logging.getLogger(__name__)
2828

2929

30+
def service_authority(service: str) -> str:
31+
"""The ``:authority`` to send for a push broker service target.
32+
33+
grpc puts the whole ``host:port`` target in ``:authority``. The sidecar envoy matches
34+
that against the mesh route's hostnames, which are RFC1123 names and cannot carry a
35+
port, so leaving the port on it matches no route and the worker gets a 404 back as
36+
UNIMPLEMENTED.
37+
"""
38+
host, sep, port = service.rpartition(":")
39+
return host if sep and port.isdigit() else service
40+
41+
3042
class PushTaskbrokerClient:
3143
"""
3244
Taskworker RPC client wrapper
@@ -52,7 +64,8 @@ def __init__(
5264
self._processing_pool_name = processing_pool_name or "unknown"
5365

5466
self._grpc_options: list[tuple[str, Any]] = [
55-
("grpc.max_receive_message_length", MAX_ACTIVATION_SIZE)
67+
("grpc.max_receive_message_length", MAX_ACTIVATION_SIZE),
68+
("grpc.default_authority", service_authority(service)),
5669
]
5770
if grpc_config:
5871
self._grpc_options.append(("grpc.service_config", grpc_config))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import pytest
2+
3+
from taskbroker_client.metrics import NoOpMetricsBackend
4+
from taskbroker_client.worker.push_clients import PushTaskbrokerClient, service_authority
5+
6+
7+
@pytest.mark.parametrize(
8+
"service,expected",
9+
[
10+
("task-ingest-push-broker-grpc:50051", "task-ingest-push-broker-grpc"),
11+
("task-ingest-push-broker-grpc:80", "task-ingest-push-broker-grpc"),
12+
("localhost:50051", "localhost"),
13+
("[::1]:50051", "[::1]"),
14+
("task-ingest-push-broker-grpc", "task-ingest-push-broker-grpc"),
15+
],
16+
)
17+
def test_service_authority_strips_the_port(service: str, expected: str) -> None:
18+
assert service_authority(service) == expected
19+
20+
21+
def test_client_sets_default_authority() -> None:
22+
client = PushTaskbrokerClient(
23+
service="task-ingest-push-broker-grpc:50051",
24+
application="tests",
25+
metrics=NoOpMetricsBackend(),
26+
)
27+
assert (
28+
"grpc.default_authority",
29+
"task-ingest-push-broker-grpc",
30+
) in client._grpc_options

0 commit comments

Comments
 (0)