Files
sixGuoDjango/django_定时器/团购任务.py
T

142 lines
4.8 KiB
Python
Raw Normal View History

2026-08-02 14:07:04 +08:00
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())