gateway: thread --timeout flag into DispatcherManager (fixes #894)

The api-gateway accepts a --timeout flag (default 600s) but
DispatcherManager never received it and instantiated every
per-service dispatcher with a hardcoded timeout=120. The flag
was therefore silently ignored for all per-service paths
(graph-rag, document-rag, librarian, etc.); requests over 120s
returned {"error":{"type":"gateway-error","message":"Timeout"}}
regardless of the configured value.

This adds a timeout parameter to DispatcherManager.__init__
(default 120 to preserve existing behaviour for callers that
don't pass it), stores it on self.timeout, uses it in both
dispatcher construction sites, and threads self.timeout through
from gateway/service.py where DispatcherManager is instantiated.

The default of 120 is preserved so this is a non-breaking
change. Callers that already pass timeout (none upstream today)
continue to work.
This commit is contained in:
harishkrishna17 2026-05-09 07:02:02 +00:00
parent fd8d5b2c42
commit cfe7d387a7
2 changed files with 14 additions and 3 deletions

View file

@ -135,13 +135,19 @@ class DispatcherWrapper:
class DispatcherManager:
def __init__(self, backend, config_receiver, auth,
prefix="api-gateway", queue_overrides=None):
prefix="api-gateway", queue_overrides=None,
timeout=120):
"""
``auth`` is required. It flows into the Mux for first-frame
WebSocket authentication and into downstream dispatcher
construction. There is no permissive default constructing
a DispatcherManager without an authenticator would be a
silent downgrade to no-auth on the socket path.
``timeout`` is the per-request timeout (seconds) applied to
every dispatcher this manager constructs (global services
and per-flow request/response paths). The api-gateway CLI
flag ``--timeout`` (default 600s) is plumbed in here.
"""
if auth is None:
raise ValueError(
@ -163,6 +169,10 @@ class DispatcherManager:
# Format: {"config": {"request": "...", "response": "..."}, ...}
self.queue_overrides = queue_overrides or {}
# Per-request timeout applied to all dispatchers; sourced
# from the api-gateway --timeout flag.
self.timeout = timeout
# Flows keyed by (workspace, flow_id)
self.flows = {}
# Dispatchers keyed by (workspace, flow_id, kind)
@ -291,7 +301,7 @@ class DispatcherManager:
dispatcher = global_dispatchers[kind](
backend = self.backend,
timeout = 120,
timeout = self.timeout,
consumer = consumer_name,
subscriber = consumer_name,
request_queue = request_queue,
@ -448,7 +458,7 @@ class DispatcherManager:
backend = self.backend,
request_queue = qconfig["request"],
response_queue = qconfig["response"],
timeout = 120,
timeout = self.timeout,
consumer = f"{self.prefix}-{workspace}-{flow}-{kind}-request",
subscriber = f"{self.prefix}-{workspace}-{flow}-{kind}-request",
)

View file

@ -119,6 +119,7 @@ class Api:
prefix = "gateway",
queue_overrides = queue_overrides,
auth = self.auth,
timeout = self.timeout,
)
self.endpoint_manager = EndpointManager(