142 lines
4.8 KiB
Python
142 lines
4.8 KiB
Python
import os
|
||||
|
|
|
|||
|
|
import django
|
|||
|
|
|
|||
|
|
from sixGuoDjango.settings import BASE_DIR
|
|||
|
|
|
|||
|
|
os.environ.setdefault(key="DJANGO_SETTINGS_MODULE", value=f"{BASE_DIR.name}.settings")
|
|||
|
|
django.setup()
|
|||
|
|
|
|||
|
|
# timer_manager.py
|
|||
|
|
import threading
|
|||
|
|
import secrets
|
|||
|
|
from datetime import datetime, timedelta
|
|||
|
|
from zoneinfo import ZoneInfo
|
|||
|
|
|
|||
|
|
from apscheduler.jobstores.base import JobLookupError
|
|||
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|||
|
|
from apscheduler.jobstores.memory import MemoryJobStore
|
|||
|
|
from apscheduler.executors.pool import ThreadPoolExecutor
|
|||
|
|
|
|||
|
|
from django_定时器.幸运拼团数据库 import lucky拼团
|
|||
|
|
from wechat_数据库.雪花算法.雪花算法工具 import generator
|
|||
|
|
|
|||
|
|
|
|||
|
|
class TwoHourWindowManager:
|
|||
|
|
"""
|
|||
|
|
团购任务
|
|||
|
|
"""
|
|||
|
|
_instance = None
|
|||
|
|
_lock = threading.Lock()
|
|||
|
|
|
|||
|
|
def __new__(cls):
|
|||
|
|
if cls._instance is None:
|
|||
|
|
with cls._lock:
|
|||
|
|
if cls._instance is None:
|
|||
|
|
cls._instance = super().__new__(cls)
|
|||
|
|
cls._instance._initialized = False
|
|||
|
|
return cls._instance
|
|||
|
|
|
|||
|
|
def __init__(self):
|
|||
|
|
if self._initialized:
|
|||
|
|
return
|
|||
|
|
self._initialized = True
|
|||
|
|
self.generate_str_id = None
|
|||
|
|
# 共享状态
|
|||
|
|
self.items = []
|
|||
|
|
self.current_cleanup_job_id: str | None = None
|
|||
|
|
self.state_lock = threading.RLock() # 保护 items 和 job_id
|
|||
|
|
# 在这里,需要对数据库的数据进行处理
|
|||
|
|
self.init初始化数据库()
|
|||
|
|
# 初始化调度器(单例)
|
|||
|
|
jobstores = {'default': MemoryJobStore()}
|
|||
|
|
executors = {'default': ThreadPoolExecutor(max_workers=2)}
|
|||
|
|
self.scheduler = BackgroundScheduler(
|
|||
|
|
jobstores=jobstores, executors=executors, timezone='Asia/Shanghai', # 替换为你的 settings.TIME_ZONE
|
|||
|
|
)
|
|||
|
|
self.scheduler.start()
|
|||
|
|
# 启动初始清理任务(2小时后)
|
|||
|
|
self._schedule_cleanup()
|
|||
|
|
|
|||
|
|
def 开团重置(self):
|
|||
|
|
"""APScheduler 调用的清理函数"""
|
|||
|
|
with self.state_lock:
|
|||
|
|
print("开团重置任务触发了啦")
|
|||
|
|
|
|||
|
|
print(f"[{datetime.now()}] ⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰⏰ 定时器到期,清空列表(当前 {len(self.items)} 项)")
|
|||
|
|
self.items.clear()
|
|||
|
|
self.current_cleanup_job_id = None # 任务已执行,ID 失效
|
|||
|
|
self.init初始化数据库()
|
|||
|
|
self._schedule_cleanup() # 开启新的任务
|
|||
|
|
print("开启新的任务")
|
|||
|
|
|
|||
|
|
def init初始化数据库(self):
|
|||
|
|
print("初始化数据库执行中")
|
|||
|
|
generate_str = generator.generate_str()
|
|||
|
|
创建对象 = lucky拼团.objects.create(idKey=generate_str, lucky拼团详细=[])
|
|||
|
|
self.generate_str_id = 创建对象.idKey
|
|||
|
|
|
|||
|
|
def _schedule_cleanup(self):
|
|||
|
|
"""安排一个新的 2 小时后清理任务"""
|
|||
|
|
with self.state_lock:
|
|||
|
|
# 取消旧任务(如果存在且未执行)
|
|||
|
|
if self.current_cleanup_job_id is not None:
|
|||
|
|
print("存在旧的任务的吗?")
|
|||
|
|
try:
|
|||
|
|
self.scheduler.remove_job(self.current_cleanup_job_id)
|
|||
|
|
print("存在旧的任务的吗?")
|
|||
|
|
pass
|
|||
|
|
except JobLookupError:
|
|||
|
|
pass # 可能已被执行或不存在
|
|||
|
|
print("打印报错", JobLookupError)
|
|||
|
|
|
|||
|
|
# 添加新任务
|
|||
|
|
job = self.scheduler.add_job(
|
|||
|
|
func=self.开团重置,
|
|||
|
|
trigger='date',
|
|||
|
|
run_date=datetime.now(tz=ZoneInfo("Asia/Shanghai")) + timedelta(seconds=7200),
|
|||
|
|
id=f"cleanup_{secrets.token_hex(8)}",
|
|||
|
|
name="Auto Cleanup",
|
|||
|
|
)
|
|||
|
|
self.current_cleanup_job_id = job.id
|
|||
|
|
print(f"[{datetime.now()}] 🕒 新建清理任务,2小时后执行,ID: {job.id}")
|
|||
|
|
|
|||
|
|
def add_item(self, item):
|
|||
|
|
"""外部调用:安全地添加元素"""
|
|||
|
|
with self.state_lock:
|
|||
|
|
self.items.append(item)
|
|||
|
|
print(f"[{datetime.now()}] ➕ 添加: {item}, 当前列表: {self.items}")
|
|||
|
|
if len(self.items) >= 4:
|
|||
|
|
print(f"[{datetime.now()}] 🧹 列表已满,立即清空并重置2小时计时器")
|
|||
|
|
self.items.clear()
|
|||
|
|
self._schedule_cleanup() # 重置计时器
|
|||
|
|
|
|||
|
|
def get_items(self):
|
|||
|
|
"""
|
|||
|
|
:return:
|
|||
|
|
:rtype:
|
|||
|
|
"""
|
|||
|
|
with self.state_lock:
|
|||
|
|
return self.items.copy()
|
|||
|
|
|
|||
|
|
def shutdown(self):
|
|||
|
|
"""
|
|||
|
|
"""
|
|||
|
|
self.scheduler.shutdown()
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == '__main__':
|
|||
|
|
pass
|
|||
|
|
# main.py 或 views.py
|
|||
|
|
# from timer_manager import TwoHourWindowManager
|
|||
|
|
|
|||
|
|
# 获取单例实例
|
|||
|
|
window = TwoHourWindowManager()
|
|||
|
|
|
|||
|
|
# 添加元素(可在多线程/Web请求中调用)
|
|||
|
|
window.add_item("user_123")
|
|||
|
|
window.add_item("order_456")
|
|||
|
|
|
|||
|
|
# 查看当前状态
|
|||
|
|
print("当前列表:", window.get_items())
|