mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 13:16:24 +00:00
fix(gateway): treat a blank GATEWAY_WORKERS and Lark broker port/timeout as unset (#5840)
Follows #5801 for the remaining numeric env reads that break on an empty value (`-e VAR=`, or `${VAR}` with VAR unset): - The WeChat QR worker guard read a blank GATEWAY_WORKERS as an invalid count and refused QR login, although the compose command starts one worker for it (`--workers ${GATEWAY_WORKERS:-1}`) and the other worker checks treat it as 1. A blank value now falls through to WEB_CONCURRENCY and then 1, so the guard still fails closed for real multi-worker setups. - The Lark broker aborted startup on int("") for a blank DEERFLOW_LARK_BROKER_PORT or DEERFLOW_LARK_BROKER_TIMEOUT; it now uses the defaults. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1da284bb3a
commit
e68b4e14e4
@ -747,8 +747,9 @@ async def _require_wechat_qr_login(request: Request) -> ChannelConnectionsConfig
|
||||
# QR sessions and mutation locks live in one process. Reject every QR route
|
||||
# before session access when requests could land on different workers.
|
||||
# WEB_CONCURRENCY is Uvicorn's fallback when no worker count is supplied.
|
||||
# A blank value means "unset", as the compose command's ${GATEWAY_WORKERS:-1} treats it.
|
||||
try:
|
||||
workers = int(os.environ.get("GATEWAY_WORKERS", os.environ.get("WEB_CONCURRENCY", "1")))
|
||||
workers = int(os.environ.get("GATEWAY_WORKERS") or os.environ.get("WEB_CONCURRENCY") or "1")
|
||||
except ValueError:
|
||||
workers = 0
|
||||
if workers != 1:
|
||||
|
||||
@ -430,8 +430,9 @@ def _config_from_env() -> BrokerConfig:
|
||||
config_dir=os.environ.get("LARKSUITE_CLI_CONFIG_DIR", "/var/lark/config"),
|
||||
data_dir=os.environ.get("LARKSUITE_CLI_DATA_DIR", "/var/lark/data"),
|
||||
host=os.environ.get("DEERFLOW_LARK_BROKER_HOST", LARK_BROKER_DEFAULT_HOST),
|
||||
port=int(os.environ.get("DEERFLOW_LARK_BROKER_PORT", str(LARK_BROKER_DEFAULT_PORT))),
|
||||
timeout_seconds=int(os.environ.get("DEERFLOW_LARK_BROKER_TIMEOUT", str(LARK_BROKER_DEFAULT_TIMEOUT_SECONDS))),
|
||||
# A blank value means "unset" (`-e DEERFLOW_LARK_BROKER_PORT=`); int("") would abort startup.
|
||||
port=int(os.environ.get("DEERFLOW_LARK_BROKER_PORT") or LARK_BROKER_DEFAULT_PORT),
|
||||
timeout_seconds=int(os.environ.get("DEERFLOW_LARK_BROKER_TIMEOUT") or LARK_BROKER_DEFAULT_TIMEOUT_SECONDS),
|
||||
deny_subcommands=parse_deny_subcommands(os.environ.get(LARK_BROKER_DENY_SUBCOMMANDS_ENV)),
|
||||
)
|
||||
|
||||
|
||||
@ -1226,7 +1226,7 @@ def test_disconnect_connection_is_current_user_scoped(tmp_path):
|
||||
anyio.run(repo.close)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("worker_env", [{}, {"GATEWAY_WORKERS": "1"}, {"WEB_CONCURRENCY": "1"}])
|
||||
@pytest.mark.parametrize("worker_env", [{}, {"GATEWAY_WORKERS": "1"}, {"WEB_CONCURRENCY": "1"}, {"GATEWAY_WORKERS": ""}])
|
||||
def test_wechat_qr_login_saves_credentials_without_exposing_token(monkeypatch, worker_env):
|
||||
from app.channels.wechat_qr_login import WechatQRLogin
|
||||
|
||||
@ -1366,7 +1366,17 @@ def test_wechat_qr_confirmation_preserves_bot_id_unless_replaced(monkeypatch, re
|
||||
assert saved == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("worker_env", [{"GATEWAY_WORKERS": "2"}, {"GATEWAY_WORKERS": "4"}, {"WEB_CONCURRENCY": "2"}, {"GATEWAY_WORKERS": "invalid"}])
|
||||
@pytest.mark.parametrize(
|
||||
"worker_env",
|
||||
[
|
||||
{"GATEWAY_WORKERS": "2"},
|
||||
{"GATEWAY_WORKERS": "4"},
|
||||
{"WEB_CONCURRENCY": "2"},
|
||||
{"GATEWAY_WORKERS": "invalid"},
|
||||
# A blank GATEWAY_WORKERS is unset, so WEB_CONCURRENCY still decides.
|
||||
{"GATEWAY_WORKERS": "", "WEB_CONCURRENCY": "2"},
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("method,suffix", [("POST", ""), ("POST", "/session/poll"), ("DELETE", "/session")])
|
||||
def test_wechat_qr_routes_reject_unsupported_workers_before_session_access(monkeypatch, worker_env, method, suffix):
|
||||
from app.channels.wechat_qr_login import WechatQRLogin
|
||||
|
||||
@ -355,3 +355,15 @@ def test_allowed_subcommand_still_runs_with_denylist(tmp_path: Path) -> None:
|
||||
assert result.exit_code == 0
|
||||
payload = json.loads(result.stdout.decode())
|
||||
assert payload["argv"] == ["auth", "status"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", ["DEERFLOW_LARK_BROKER_PORT", "DEERFLOW_LARK_BROKER_TIMEOUT"])
|
||||
def test_config_from_env_treats_blank_numbers_as_unset(monkeypatch, name) -> None:
|
||||
monkeypatch.delenv("DEERFLOW_LARK_BROKER_PORT", raising=False)
|
||||
monkeypatch.delenv("DEERFLOW_LARK_BROKER_TIMEOUT", raising=False)
|
||||
monkeypatch.setenv(name, "")
|
||||
|
||||
config = lark_broker._config_from_env()
|
||||
|
||||
assert config.port == lark_broker.LARK_BROKER_DEFAULT_PORT
|
||||
assert config.timeout_seconds == lark_broker.LARK_BROKER_DEFAULT_TIMEOUT_SECONDS
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user