You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
3.4 KiB
81 lines
3.4 KiB
#!/usr/bin/env python
|
|
# -*- coding:utf-8 -*-
|
|
# project: 3月
|
|
# author: NinEveN
|
|
# date: 2022/3/15
|
|
import logging
|
|
import time
|
|
|
|
from django.core.cache import cache
|
|
|
|
from common.cache.storage import PendingStateCache
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def set_pending_cache(unique_key, cache_data, cache_obj, timeout):
|
|
if unique_key in cache_data:
|
|
cache_data.remove(unique_key)
|
|
logger.warning(f'return unique_key:{unique_key} cache_data: {cache_data} ')
|
|
cache_obj.set_storage_cache(cache_data, timeout)
|
|
|
|
|
|
def get_pending_result(func, expect_func, loop_count=10, sleep_time=3, unique_key='default_key',
|
|
run_func_count=2, pop_first=True, *args, **kwargs):
|
|
"""
|
|
:param func: 将要运行的函数对象
|
|
:param expect_func: 期待的运行结果函数
|
|
:param loop_count: 执行次数
|
|
:param sleep_time: 执行循环等待时间
|
|
:param unique_key: 11请求唯一标识,用与函数并发请求
|
|
:param run_func_count: 11函数并发请求数,超过该次数,会自动移除多余等待
|
|
:param pop_first: 11超出,是否自动移除最老的请求,True: 移除最老的, False: 移除最新的
|
|
:param args:
|
|
:param kwargs:
|
|
:return:
|
|
"""
|
|
locker_key = kwargs.pop('locker_key')
|
|
cache_timeout = loop_count * sleep_time * (run_func_count + 1)
|
|
cache_obj = PendingStateCache(locker_key)
|
|
cache_data = cache_obj.get_storage_cache()
|
|
is_pop = False
|
|
if cache_data and isinstance(cache_data, list):
|
|
if unique_key not in cache_data:
|
|
cache_data.append(unique_key)
|
|
if len(cache_data) > run_func_count and len(cache_data) > 0:
|
|
is_pop = True
|
|
if pop_first:
|
|
cache_data.pop(0)
|
|
else:
|
|
cache_data.pop()
|
|
else:
|
|
cache_data = [unique_key]
|
|
|
|
cache_obj.set_storage_cache(cache_data, cache_timeout)
|
|
if not pop_first and len(cache_data) == run_func_count and is_pop:
|
|
logger.warning(f'unique_key:{unique_key} cache_data: {cache_data} ')
|
|
return True, {'err_msg': '请求重复,请稍后再试'}
|
|
try:
|
|
with cache.lock(f"get_pending_result_{locker_key}", timeout=loop_count * sleep_time):
|
|
count = 1
|
|
while True:
|
|
cache_data = cache_obj.get_storage_cache()
|
|
logger.warning(f'unique_key:{unique_key} cache_data: {cache_data} ')
|
|
if cache_data and isinstance(cache_data, list) and unique_key in cache_data:
|
|
result = func(*args, **kwargs)
|
|
if expect_func(result, *args, **kwargs):
|
|
set_pending_cache(unique_key, cache_data, cache_obj, cache_timeout)
|
|
return True, {'data': result}
|
|
time.sleep(sleep_time)
|
|
if loop_count < count:
|
|
set_pending_cache(unique_key, cache_data, cache_obj, cache_timeout)
|
|
return False, {'err_msg': '请求超时'}
|
|
count += 1
|
|
else:
|
|
set_pending_cache(unique_key, cache_data, cache_obj, cache_timeout)
|
|
return True, {'err_msg': '请求重复,请稍后再试'}
|
|
|
|
except Exception as e:
|
|
logger.warning(f'get pending result exception: {e}')
|
|
set_pending_cache(unique_key, cache_data, cache_obj, cache_timeout)
|
|
return False, {'err_msg': '内部错误'}
|
|
|