{"record":{"id":"8dea6808fb8c586e","repo":"ZhuLinsen/daily_stock_analysis","slug":"wait-seconds-g-s","errorCode":null,"errorMessage":"题材新闻搜索超过 {wait_seconds:g}s，已终止请求进程","messagePattern":"题材新闻搜索超过 (.+?)s，已终止请求进程","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"warning","filePath":"src/search_service.py","lineNumber":141,"sourceCode":"                    max_results,\n                    focus_keywords,\n                ),\n                name=\"search-topic-news\",\n                daemon=True,\n            )\n            process.start()\n            process_started = True\n            child_conn.close()\n            child_conn = None\n\n            poll_seconds = (\n                wait_seconds\n                if deadline is None\n                else max(0.0, deadline - time.monotonic())\n            )\n            if poll_seconds <= 0 or not parent_conn.poll(poll_seconds):\n                _terminate_search_process(process)\n                raise TimeoutError(f\"题材新闻搜索超过 {wait_seconds:g}s，已终止请求进程\")\n            try:\n                ok, value = parent_conn.recv()\n            except EOFError as exc:\n                raise RuntimeError(\"题材新闻搜索进程未返回结果\") from exc\n        finally:\n            try:\n                if child_conn is not None:\n                    child_conn.close()\n            finally:\n                try:\n                    if parent_conn is not None:\n                        parent_conn.close()\n                finally:\n                    if process_started:\n                        try:\n                            process.join(_SEARCH_TIMEOUT_PROCESS_JOIN_GRACE_SECONDS)\n                        finally:\n                            _terminate_search_process(process)","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/search_service.py#L123-L159","documentation":"TimeoutError from _call_topic_news_in_subprocess: the worker process did not produce a result on the pipe within the effective wait window (timeout_seconds, or the remaining time to an optional deadline). The parent terminates the worker (_terminate_search_process) before raising, so no zombie remains. It means the provider chain was too slow or hung.","triggerScenarios":"A topic-news provider (e.g. a slow scraping chain) exceeding the per-call timeout; an overall deadline already nearly exhausted so poll_seconds <= 0 raises immediately; worker blocked on network I/O without its own internal timeouts.","commonSituations":"Upstream search engines rate-limiting or hanging; timeout configured lower than realistic provider latency; a burst of searches making each subprocess slower; network egress blocked in a container so requests hang until the deadline.","solutions":["Increase the topic-news timeout so it covers realistic provider latency","Retry the search once — transient provider slowness is common and the worker is cleanly terminated each time","Check egress connectivity/DNS from the container if timeouts are consistent rather than sporadic","Profile which provider in the chain is slow and tighten its individual timeout or remove it from the chain"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"def deadline_feasible(deadline: float, timeout_seconds: float) -> bool:\n    return deadline is None or deadline - time.monotonic() > timeout_seconds","typeGuard":null,"tryCatchPattern":"try:\n    resp = search_topic_news(topic, timeout_seconds=30)\nexcept TimeoutError as exc:\n    log.warning(\"Topic news slow for %r: %s — retrying once\", topic, exc)\n    resp = search_topic_news(topic, timeout_seconds=60)  # or degrade to no-news","preventionTips":["Size the search timeout above the slowest expected provider in the chain","Cache topic results so slow topics are not re-searched on every request","Verify container egress/DNS when timeouts become consistent"],"tags":["timeout","search","subprocess","network"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}