2. 确认超时处理
任务目标
为确认机制增加超时处理能力:当用户发起一个需要确认的操作后,系统等待用户响应;若在指定时间内(如10秒)未收到确认或拒绝指令,则自动取消该操作,并将超时事件写入日志。
核心实现
import time
import threading
import logging
from enum import Enum
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger("confirmation")
class ConfirmResult(Enum):
CONFIRMED = "confirmed"
REJECTED = "rejected"
TIMEOUT = "timeout"
class ConfirmationTimeout:
def __init__(self, timeout_seconds=10):
self.timeout = timeout_seconds
self._result = None
self._event = threading.Event()
self._timer = None
def _on_timeout(self):
"""超时回调:设置结果为TIMEOUT并唤醒等待线程"""
self._result = ConfirmResult.TIMEOUT
self._event.set()
logger.warning(f"确认超时({self.timeout}秒未响应),操作已自动取消")
def wait_for_response(self):
"""启动超时计时,等待用户确认/拒绝/超时"""
self._timer = threading.Timer(self.timeout, self._on_timeout)
self._timer.start()
self._event.wait() # 阻塞直到用户响应或超时
self._timer.cancel()
return self._result
def confirm(self):
"""用户点击确认"""
self._result = ConfirmResult.CONFIRMED
self._event.set()
logger.info("用户已确认,操作继续执行")
def reject(self):
"""用户点击拒绝"""
self._result = ConfirmResult.REJECTED
self._event.set()
logger.info("用户已拒绝,操作已取消")
def execute_operation_with_confirmation(operation_name, timeout_seconds=10):
"""
带超时确认的操作执行入口。
返回 (ConfirmResult, 是否执行)
"""
confirmation = ConfirmationTimeout(timeout_seconds)
print(f"操作「{operation_name}」需要确认,请在{timeout_seconds}秒内输入 y(确认)/ n(拒绝)")
# 模拟用户输入线程(实际项目中替换为GUI/API回调)
def simulate_user_input():
user_input = input("> ").strip().lower()
if user_input == 'y':
confirmation.confirm()
elif user_input == 'n':
confirmation.reject()
# 其他输入忽略,等待超时
input_thread = threading.Thread(target=simulate_user_input, daemon=True)
input_thread.start()
result = confirmation.wait_for_response()
if result == ConfirmResult.CONFIRMED:
print(f"操作「{operation_name}」已执行")
return result, True
else:
print(f"操作「{operation_name}」未执行(原因:{result.value})")
return result, False
if __name__ == "__main__":
# 演示:5秒超时
result, executed = execute_operation_with_confirmation("删除文件", timeout_seconds=5)
print(f"最终结果: {result.value}, 操作执行: {executed}")
运行与验证
运行方式:
python confirmation_timeout.py
验证路径(三种场景):
- 确认路径:程序启动后5秒内输入
y,观察日志输出“用户已确认”,控制台显示“操作已执行”,返回confirmed。 - 拒绝路径:程序启动后5秒内输入
n,观察日志输出“用户已拒绝”,控制台显示“操作未执行”,返回rejected。 - 超时路径:程序启动后不做任何输入,等待5秒,观察日志输出“确认超时”,控制台显示“操作未执行(原因:timeout)”,返回
timeout。
判定标准:三种场景下,wait_for_response() 均能正确返回对应 ConfirmResult 枚举值;超时场景下操作被自动取消且日志中记录了超时事件;确认/拒绝场景下计时器被正确取消,不会在用户响应后再次触发超时回调。
关键设计说明
- 使用
threading.Timer实现非阻塞超时计时,避免time.sleep()阻塞主流程。 threading.Event用于协调用户响应与超时回调之间的竞争条件——无论哪个先发生,wait_for_response()都会立即返回。- 超时回调中调用
logger.warning记录日志,实际项目中可替换为文件日志或审计系统。 - 示例中的
simulate_user_input仅为演示控制台交互,生产环境应替换为GUI按钮回调、API接口或消息队列事件。