ZhuLinsen/daily_stock_analysis · warning · TimeoutError

题材新闻搜索超过 {wait_seconds:g}s,已终止请求进程

Error message

题材新闻搜索超过 {wait_seconds:g}s,已终止请求进程

What it means

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.

Source

Thrown at src/search_service.py:141

                    max_results,
                    focus_keywords,
                ),
                name="search-topic-news",
                daemon=True,
            )
            process.start()
            process_started = True
            child_conn.close()
            child_conn = None

            poll_seconds = (
                wait_seconds
                if deadline is None
                else max(0.0, deadline - time.monotonic())
            )
            if poll_seconds <= 0 or not parent_conn.poll(poll_seconds):
                _terminate_search_process(process)
                raise TimeoutError(f"题材新闻搜索超过 {wait_seconds:g}s,已终止请求进程")
            try:
                ok, value = parent_conn.recv()
            except EOFError as exc:
                raise RuntimeError("题材新闻搜索进程未返回结果") from exc
        finally:
            try:
                if child_conn is not None:
                    child_conn.close()
            finally:
                try:
                    if parent_conn is not None:
                        parent_conn.close()
                finally:
                    if process_started:
                        try:
                            process.join(_SEARCH_TIMEOUT_PROCESS_JOIN_GRACE_SECONDS)
                        finally:
                            _terminate_search_process(process)

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Increase the topic-news timeout so it covers realistic provider latency
  2. Retry the search once — transient provider slowness is common and the worker is cleanly terminated each time
  3. Check egress connectivity/DNS from the container if timeouts are consistent rather than sporadic
  4. Profile which provider in the chain is slow and tighten its individual timeout or remove it from the chain
Defensive patterns

Strategy: retry

Validate before calling

def deadline_feasible(deadline: float, timeout_seconds: float) -> bool:
    return deadline is None or deadline - time.monotonic() > timeout_seconds

Try / catch

try:
    resp = search_topic_news(topic, timeout_seconds=30)
except TimeoutError as exc:
    log.warning("Topic news slow for %r: %s — retrying once", topic, exc)
    resp = search_topic_news(topic, timeout_seconds=60)  # or degrade to no-news

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/8dea6808fb8c586e. Report an issue: GitHub.