init
This commit is contained in:
55
utils/image_queue.py
Normal file
55
utils/image_queue.py
Normal file
@@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
图片处理队列 - 高并发时排队,避免打满 API
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 信号量限制并发数
|
||||
_semaphore: Optional[asyncio.Semaphore] = None
|
||||
_queue_size = 0
|
||||
_max_concurrent = 2
|
||||
_max_queue = 20
|
||||
|
||||
|
||||
def init(max_concurrent: int = None, max_queue: int = None):
|
||||
"""初始化队列(在 workflow 使用前调用)"""
|
||||
global _semaphore, _max_concurrent, _max_queue
|
||||
try:
|
||||
from config.config import IMAGE_QUEUE_MAX_CONCURRENT, IMAGE_QUEUE_MAX_SIZE
|
||||
_max_concurrent = max_concurrent or IMAGE_QUEUE_MAX_CONCURRENT
|
||||
_max_queue = max_queue or IMAGE_QUEUE_MAX_SIZE
|
||||
except Exception:
|
||||
_max_concurrent = max_concurrent or 2
|
||||
_max_queue = max_queue or 20
|
||||
_semaphore = asyncio.Semaphore(_max_concurrent)
|
||||
|
||||
|
||||
async def acquire():
|
||||
"""获取处理槽位,队列满时等待"""
|
||||
global _queue_size
|
||||
if _semaphore is None:
|
||||
init()
|
||||
if _queue_size >= _max_queue:
|
||||
logger.warning(f"[图片队列] 队列已满({_queue_size}),等待空位...")
|
||||
_queue_size += 1
|
||||
await _semaphore.acquire()
|
||||
_queue_size -= 1
|
||||
|
||||
|
||||
def release():
|
||||
"""释放槽位"""
|
||||
if _semaphore:
|
||||
_semaphore.release()
|
||||
|
||||
|
||||
async def run_with_queue(coro):
|
||||
"""在队列中执行协程"""
|
||||
await acquire()
|
||||
try:
|
||||
return await coro
|
||||
finally:
|
||||
release()
|
||||
Reference in New Issue
Block a user