{"record":{"id":"2aeebe8311aad547","repo":"666ghj/MiroFish","slug":"timeout","errorCode":null,"errorMessage":"等待命令响应超时 ({timeout}秒)","messagePattern":"等待命令响应超时 \\((.+?)秒\\)","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"backend/app/services/simulation_ipc.py","lineNumber":187,"sourceCode":"                        pass\n                    \n                    logger.info(f\"收到IPC响应: command_id={command_id}, status={response.status.value}\")\n                    return response\n                except (json.JSONDecodeError, KeyError) as e:\n                    logger.warning(f\"解析响应失败: {e}\")\n            \n            time.sleep(poll_interval)\n        \n        # 超时\n        logger.error(f\"等待IPC响应超时: command_id={command_id}\")\n        \n        # 清理命令文件\n        try:\n            os.remove(command_file)\n        except OSError:\n            pass\n        \n        raise TimeoutError(f\"等待命令响应超时 ({timeout}秒)\")\n    \n    def send_interview(\n        self,\n        agent_id: int,\n        prompt: str,\n        platform: str = None,\n        timeout: float = 60.0\n    ) -> IPCResponse:\n        \"\"\"\n        发送单个Agent采访命令\n        \n        Args:\n            agent_id: Agent ID\n            prompt: 采访问题\n            platform: 指定平台（可选）\n                - \"twitter\": 只采访Twitter平台\n                - \"reddit\": 只采访Reddit平台  \n                - None: 双平台模拟时同时采访两个平台，单平台模拟时采访该平台","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/666ghj/MiroFish/blob/b5b53acc57189a4a42e44a23e149dc655c98fe82/backend/app/services/simulation_ipc.py#L169-L205","documentation":"Raised by SimulationIPCClient.send_command: file-based IPC writes a command JSON into the commands dir, then polls every poll_interval (0.5s default) for a response file {command_id}.json in the responses dir. If no valid response appears within timeout (default 60s), it removes the command file and raises TimeoutError. This means the OASIS simulation subprocess is not consuming commands or is too slow to answer.","triggerScenarios":"Simulation process not started, crashed, or not watching the commands directory; response written after the deadline; response file present but unparseable (json.JSONDecodeError/KeyError in IPCResponse.from_dict is logged and skipped, so a malformed response also manifests as a timeout); commands/responses dirs pointing at different paths than the subprocess uses.","commonSituations":"Subprocess died earlier (check its logs) while the backend still sends interview/round commands; Docker volume mismatch so the two processes see different dirs; a long-running interview exceeding the 60s default timeout; concurrent runs sharing a directory with stale files; partially written response file read mid-write.","solutions":["Check that the OASIS simulation subprocess is alive and its logs show it consuming the command file; restart it if crashed.","Verify both processes agree on the commands/responses directories (absolute paths, same volume in Docker).","Increase the timeout argument for slow operations like interviews (send_interview supports timeout=60 default).","If logs show '解析响应失败', the response file is malformed — ensure the subprocess writes atomically (temp file + rename) and matches IPCResponse.from_dict's expected keys."],"exampleFix":"# before\nresp = ipc.send_command(CommandType.INTERVIEW, args, timeout=60)\n# after\nresp = ipc.send_command(CommandType.INTERVIEW, args, timeout=180)\n# plus: subprocess should write responses atomically\n# tmp = response_file + '.tmp'; write; os.replace(tmp, response_file)","handlingStrategy":"retry","validationCode":"def subprocess_alive(pid_file: str) -> bool:\n    try:\n        pid = int(open(pid_file).read().strip())\n        os.kill(pid, 0)\n        return True\n    except (OSError, ValueError):\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    resp = ipc.send_command(cmd, args, timeout=180)\nexcept TimeoutError:\n    if not subprocess_alive():\n        restart_simulation_subprocess()\n    resp = ipc.send_command(cmd, args, timeout=180)  # one bounded retry","preventionTips":["Health-check the simulation subprocess before sending commands; restart on death.","Write IPC files atomically (temp + os.replace) so half-written responses aren't read.","Scale the timeout to the command type (interviews are slow; use send_interview's timeout)."],"tags":["ipc","file-based","timeout","subprocess","simulation"],"backgroundTag":null,"analyzedSha":"b5b53acc57189a4a42e44a23e149dc655c98fe82","analyzedAt":"2026-08-14T22:29:33.146Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}