import multiprocessing import os import threading import time from enum import Enum from typing import Any from flask import Blueprint, g, current_app from flask_app.general.format_change import download_file from flask_app.routes.判断是否是招标文件 import judge_zbfile_exec from flask_app.routes.utils import validate_and_setup_logger, create_response_normal, log_error_unique_id judge_zbfile_bp = Blueprint('judge_zbfile', __name__) class JudgeResult(Enum): ERROR = 1 YES = 2 NO = 3 @judge_zbfile_bp.route('/judge_zbfile', methods=['POST']) @validate_and_setup_logger # @require_connection_limit(timeout=30) def judge_zbfile() -> Any: #判断是否是招标文件 """ 主函数,调用 wrapper 并设置整个接口的超时时时间。如果超时返回默认值。 """ logger = g.logger file_url = g.file_url output_folder = g.output_folder unique_id = g.unique_id result = [None] # 用于存储结果的可变对象 done = threading.Event() # 标志判断是否完成 pool = current_app.process_pool # 使用全局的进程池 def judge_zbfile_exec_sub(file_path): result = pool.apply( judge_zbfile_exec, # 你的实际执行函数 args=(file_path,) ) return result def wrapper() -> None: """ 包装整个 judge_zbfile 的函数逻辑 """ try: start_time = time.time() downloaded_filename = os.path.join(output_folder, "ztbfile") logger.info(f"接收到的url:{file_url}") downloaded_filepath, file_type = download_file(file_url, downloaded_filename,True) if not downloaded_filepath or file_type == 4: log_error_unique_id(unique_id, 4) result[0] = JudgeResult.ERROR return logger.info(f"Local file path: {downloaded_filepath}") # 调用实际的判断函数 judge_result = judge_zbfile_exec_sub(downloaded_filepath) judge = JudgeResult.YES if judge_result else JudgeResult.NO end_time = time.time() logger.info(f"接口实际耗时:{end_time - start_time:.2f} 秒") result[0] = judge except Exception as e: logger.error(f'Exception occurred: {e}') log_error_unique_id(unique_id, 4) result[0] = JudgeResult.ERROR finally: done.set() # 启动后台线程执行 wrapper thread = threading.Thread(target=wrapper, daemon=True) thread.start() # ****设置整个接口的超时时间,如果超时,会默认返回create_response_normal,但wrapper()仍继续执行! timeout = 15 finished_in_time = done.wait(timeout) if not finished_in_time: logger.warning("整个接口执行超时,返回默认值 'yes'") # 如果超时,返回默认响应 return create_response_normal( message='判断是否为招标文件成功!', status='success', data='yes' # 默认返回值 ) else: return build_response(result[0], logger) def build_response(judge_result: JudgeResult, logger) -> Any: """ 根据 judge_result 构建响应 """ if judge_result == JudgeResult.ERROR: logger.error("下载地址不存在或不支持的文件类型!") return create_response_normal( message='下载地址不存在或不支持的文件类型!', status='error', data='' ) elif judge_result == JudgeResult.YES: logger.info("判断是否为招标文件成功!YES") return create_response_normal( message='判断是否为招标文件成功!', status='success', data='yes' ) elif judge_result == JudgeResult.NO: logger.info("判断是否为招标文件成功!NO") return create_response_normal( message='判断是否为招标文件成功!', status='success', data='no' ) else: # 处理未知的结果 logger.error("服务器遇到不知名错误!") return create_response_normal( message='服务器遇到不知名错误!', status='error', data='' )