{"record":{"id":"29d00ad115a0df58","repo":"ZhuLinsen/daily_stock_analysis","slug":"call-name","errorCode":null,"errorMessage":"{call_name} 调用进程未返回结果","messagePattern":"(.+?) 调用进程未返回结果","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"data_provider/akshare_fetcher.py","lineNumber":355,"sourceCode":"    process = ctx.Process(\n        target=_akshare_timeout_worker,\n        args=(child_conn, func, args, kwargs),\n        name=f\"akshare-{call_name}\",\n        daemon=True,\n    )\n\n    process.start()\n    child_conn.close()\n\n    try:\n        if not parent_conn.poll(wait_seconds):\n            _terminate_akshare_process(process)\n            raise TimeoutError(f\"{call_name} 调用超过 {wait_seconds:g}s，已放弃等待\")\n\n        try:\n            ok, value = parent_conn.recv()\n        except EOFError as exc:\n            raise RuntimeError(f\"{call_name} 调用进程未返回结果\") from exc\n    finally:\n        parent_conn.close()\n        process.join(_AKSHARE_TIMEOUT_PROCESS_JOIN_GRACE)\n        _terminate_akshare_process(process)\n\n    if ok:\n        return value\n    raise value\n\n\ndef _akshare_timeout_worker(conn, func, args, kwargs) -> None:\n    try:\n        conn.send((True, func(*args, **kwargs)))\n    except BaseException as exc:\n        try:\n            conn.send((False, exc))\n        except BaseException:\n            try:","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/data_provider/akshare_fetcher.py#L337-L373","documentation":"RuntimeError raised when the akshare worker process died without sending anything back: parent_conn.recv() hits EOFError because the child closed the pipe (crashed, was OOM-killed, or segfaulted inside a native dependency) before delivering the (ok, value) result. It is distinct from the timeout case — the child ended, it didn't stall.","triggerScenarios":"The multiprocessing worker calling an akshare function is killed by the OOM killer (large DataFrames in a memory-constrained container), segfaults in a C extension, or crashes on an unhandled native error; poll() succeeds but recv() raises EOFError.","commonSituations":"Docker/Kubernetes containers with low memory limits fetching long date ranges; macOS/Windows spawn start methods where unpicklable arguments kill the child; akshare/native dependency (pandas/numpy) ABI mismatch causing hard crashes.","solutions":["Check dmesg/container logs for OOM kills of the 'akshare-*' child process; raise the memory limit or narrow the date range.","Reinstall akshare, pandas and numpy so their binary versions are compatible (pip install --force-reinstall akshare).","Retry once — transient native crashes do happen under load.","If persistent for one symbol, that call likely crashes deterministically; test the akshare function standalone in a REPL to isolate it.","Let the data-provider fallback chain switch to an alternate fetcher for the affected call."],"exampleFix":"# narrow memory pressure: fetch in chunks\n# before\ndf = fetcher.fetch_stock_data('600519', '2010-01-01', '2025-01-01')\n# after\ndfs = [fetcher.fetch_stock_data('600519', y, f'{int(y)+1}-01-01') for y in range(2010, 2025)]","handlingStrategy":"fallback","validationCode":"# guard memory before batch runs\nimport shutil, os\nfree_mb = shutil.disk_usage('/').free // (1024 * 1024)\n# and check container limits; a worker OOM is the top cause of EOFError on the pipe\nassert free_mb > 512, 'low disk/memory conditions correlate with worker crashes'","typeGuard":"def is_akshare_worker_died(exc: Exception) -> bool:\n    return isinstance(exc, RuntimeError) and '调用进程未返回结果' in str(exc)","tryCatchPattern":"try:\n    df = fetcher.fetch_stock_data(code, start, end)\nexcept RuntimeError as e:\n    if '调用进程未返回结果' in str(e):\n        df = fallback_fetcher.fetch_stock_data(code, start, end)  # worker crashed; switch source\n    else:\n        raise","preventionTips":["Give containers enough memory for large DataFrame fetches, or chunk date ranges.","Keep binary deps (akshare/pandas/numpy) version-consistent to avoid native crashes in the worker.","Retry once — worker crashes are frequently transient — then fall back to another fetcher."],"tags":["akshare","multiprocessing","crash","oom","data-provider"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}