@@ -719,55 +719,66 @@ def determine_proxy_configuration(internal_camoufox_proxy_arg=None):
719719 camoufox_popen_kwargs ['creationflags' ] = subprocess .CREATE_NO_WINDOW
720720 try :
721721 logger .info (f" 将执行 Camoufox 内部启动命令: { ' ' .join (camoufox_internal_cmd_args )} " )
722- camoufox_proc = subprocess .Popen (camoufox_internal_cmd_args , ** camoufox_popen_kwargs )
723- logger .info (f' Camoufox 内部进程已启动 (PID: { camoufox_proc .pid } )。正在等待 WebSocket 端点输出 (最长 { ENDPOINT_CAPTURE_TIMEOUT } 秒)...' )
724- camoufox_output_q = queue .Queue ()
725- camoufox_stdout_reader = threading .Thread (target = _enqueue_output , args = (camoufox_proc .stdout , 'stdout' , camoufox_output_q , camoufox_proc .pid ), daemon = True )
726- camoufox_stderr_reader = threading .Thread (target = _enqueue_output , args = (camoufox_proc .stderr , 'stderr' , camoufox_output_q , camoufox_proc .pid ), daemon = True )
727- camoufox_stdout_reader .start ()
728- camoufox_stderr_reader .start ()
729- ws_capture_start_time = time .time ()
730- camoufox_ended_streams_count = 0
731- while time .time () - ws_capture_start_time < ENDPOINT_CAPTURE_TIMEOUT :
732- if camoufox_proc .poll () is not None :
733- logger .error (f' Camoufox 内部进程 (PID: { camoufox_proc .pid } ) 在等待 WebSocket 端点期间已意外退出,退出码: { camoufox_proc .poll ()} 。' )
734- break
735- try :
736- stream_name , line_from_camoufox = camoufox_output_q .get (timeout = 0.2 )
737- if line_from_camoufox is None :
738- camoufox_ended_streams_count += 1
739- logger .debug (f' [InternalCamoufox-{ stream_name } -PID:{ camoufox_proc .pid } ] 输出流已关闭 (EOF)。' )
740- if camoufox_ended_streams_count >= 2 :
741- logger .info (f' Camoufox 内部进程 (PID: { camoufox_proc .pid } ) 的所有输出流均已关闭。' )
722+ MAX_CAMOUFOX_RETRIES = 3
723+ for camoufox_attempt in range (MAX_CAMOUFOX_RETRIES ):
724+ if camoufox_attempt > 0 :
725+ logger .warning (f' 🔄 重试启动 Camoufox (第 { camoufox_attempt + 1 } /{ MAX_CAMOUFOX_RETRIES } 次)...' )
726+ camoufox_proc = subprocess .Popen (camoufox_internal_cmd_args , ** camoufox_popen_kwargs )
727+ logger .info (f' Camoufox 内部进程已启动 (PID: { camoufox_proc .pid } )。正在等待 WebSocket 端点输出 (最长 { ENDPOINT_CAPTURE_TIMEOUT } 秒)...' )
728+ camoufox_output_q = queue .Queue ()
729+ camoufox_stdout_reader = threading .Thread (target = _enqueue_output , args = (camoufox_proc .stdout , 'stdout' , camoufox_output_q , camoufox_proc .pid ), daemon = True )
730+ camoufox_stderr_reader = threading .Thread (target = _enqueue_output , args = (camoufox_proc .stderr , 'stderr' , camoufox_output_q , camoufox_proc .pid ), daemon = True )
731+ camoufox_stdout_reader .start ()
732+ camoufox_stderr_reader .start ()
733+ ws_capture_start_time = time .time ()
734+ camoufox_ended_streams_count = 0
735+ while time .time () - ws_capture_start_time < ENDPOINT_CAPTURE_TIMEOUT :
736+ if camoufox_proc .poll () is not None :
737+ logger .error (f' Camoufox 内部进程 (PID: { camoufox_proc .pid } ) 在等待 WebSocket 端点期间已意外退出,退出码: { camoufox_proc .poll ()} 。' )
738+ break
739+ try :
740+ stream_name , line_from_camoufox = camoufox_output_q .get (timeout = 0.2 )
741+ if line_from_camoufox is None :
742+ camoufox_ended_streams_count += 1
743+ logger .debug (f' [InternalCamoufox-{ stream_name } -PID:{ camoufox_proc .pid } ] 输出流已关闭 (EOF)。' )
744+ if camoufox_ended_streams_count >= 2 :
745+ logger .info (f' Camoufox 内部进程 (PID: { camoufox_proc .pid } ) 的所有输出流均已关闭。' )
746+ break
747+ continue
748+ log_line_content = f'[InternalCamoufox-{ stream_name } -PID:{ camoufox_proc .pid } ]: { line_from_camoufox .rstrip ()} '
749+ if stream_name == 'stderr' or 'ERROR' in line_from_camoufox .upper () or '❌' in line_from_camoufox :
750+ logger .warning (log_line_content )
751+ else :
752+ logger .info (log_line_content )
753+ ws_match = ws_regex .search (line_from_camoufox )
754+ if ws_match :
755+ captured_ws_endpoint = ws_match .group (1 )
756+ logger .info (f' ✅ 成功从 Camoufox 内部进程捕获到 WebSocket 端点: { captured_ws_endpoint [:40 ]} ...' )
742757 break
758+ except queue .Empty :
743759 continue
744- log_line_content = f'[InternalCamoufox-{ stream_name } -PID:{ camoufox_proc .pid } ]: { line_from_camoufox .rstrip ()} '
745- if stream_name == 'stderr' or 'ERROR' in line_from_camoufox .upper () or '❌' in line_from_camoufox :
746- logger .warning (log_line_content )
747- else :
748- logger .info (log_line_content )
749- ws_match = ws_regex .search (line_from_camoufox )
750- if ws_match :
751- captured_ws_endpoint = ws_match .group (1 )
752- logger .info (f' ✅ 成功从 Camoufox 内部进程捕获到 WebSocket 端点: { captured_ws_endpoint [:40 ]} ...' )
753- break
754- except queue .Empty :
755- continue
756- if camoufox_stdout_reader .is_alive ():
757- camoufox_stdout_reader .join (timeout = 1.0 )
758- if camoufox_stderr_reader .is_alive ():
759- camoufox_stderr_reader .join (timeout = 1.0 )
760- if not captured_ws_endpoint and (camoufox_proc and camoufox_proc .poll () is None ):
761- logger .error (f' ❌ 未能在 { ENDPOINT_CAPTURE_TIMEOUT } 秒内从 Camoufox 内部进程 (PID: { camoufox_proc .pid } ) 捕获到 WebSocket 端点。' )
762- logger .error (' Camoufox 内部进程仍在运行,但未输出预期的 WebSocket 端点。请检查其日志或行为。' )
760+ if camoufox_stdout_reader .is_alive ():
761+ camoufox_stdout_reader .join (timeout = 1.0 )
762+ if camoufox_stderr_reader .is_alive ():
763+ camoufox_stderr_reader .join (timeout = 1.0 )
764+ if captured_ws_endpoint :
765+ break
766+ # Failed - kill process and retry
767+ if camoufox_proc and camoufox_proc .poll () is None :
768+ logger .warning (f' ❌ 未能在 { ENDPOINT_CAPTURE_TIMEOUT } 秒内捕获到 WebSocket 端点,终止进程 (PID: { camoufox_proc .pid } )...' )
769+ camoufox_proc .terminate ()
770+ try :
771+ camoufox_proc .wait (timeout = 5 )
772+ except subprocess .TimeoutExpired :
773+ camoufox_proc .kill ()
774+ else :
775+ logger .warning (f' ❌ Camoufox 内部进程已退出,未能捕获到 WebSocket 端点。' )
776+ if camoufox_attempt < MAX_CAMOUFOX_RETRIES - 1 :
777+ time .sleep (3 )
778+ if not captured_ws_endpoint :
779+ logger .error (f' ❌ Camoufox 在 { MAX_CAMOUFOX_RETRIES } 次尝试后均未能输出 WebSocket 端点。' )
763780 cleanup ()
764781 sys .exit (1 )
765- elif not captured_ws_endpoint and (camoufox_proc and camoufox_proc .poll () is not None ):
766- logger .error (f' ❌ Camoufox 内部进程已退出,且未能捕获到 WebSocket 端点。' )
767- sys .exit (1 )
768- elif not captured_ws_endpoint :
769- logger .error (f' ❌ 未能捕获到 WebSocket 端点。' )
770- sys .exit (1 )
771782 except Exception as e_launch_camoufox_internal :
772783 logger .critical (f' ❌ 在内部启动 Camoufox 或捕获其 WebSocket 端点时发生致命错误: { e_launch_camoufox_internal } ' , exc_info = True )
773784 cleanup ()
0 commit comments