mirror of https://github.com/jumpserver/jumpserver
perf: 优化延迟运行
fix: 延迟执行设置超时 perf: 修改 delay run perf: 优化 delay_run 执行 perf: 修改 delay runpull/12169/head
parent
452b383278
commit
07e1918fa1
|
@ -8,7 +8,7 @@ from django.utils.translation import gettext as _
|
||||||
from rest_framework import authentication, exceptions
|
from rest_framework import authentication, exceptions
|
||||||
|
|
||||||
from common.auth import signature
|
from common.auth import signature
|
||||||
from common.decorators import delay_run
|
from common.decorators import merge_delay_run
|
||||||
from common.utils import get_object_or_none, get_request_ip_or_data, contains_ip
|
from common.utils import get_object_or_none, get_request_ip_or_data, contains_ip
|
||||||
from ..models import AccessKey, PrivateToken
|
from ..models import AccessKey, PrivateToken
|
||||||
|
|
||||||
|
@ -17,22 +17,24 @@ def date_more_than(d, seconds):
|
||||||
return d is None or (timezone.now() - d).seconds > seconds
|
return d is None or (timezone.now() - d).seconds > seconds
|
||||||
|
|
||||||
|
|
||||||
@delay_run(ttl=60)
|
@merge_delay_run(ttl=60)
|
||||||
def update_token_last_used(token):
|
def update_token_last_used(tokens=()):
|
||||||
token.date_last_used = timezone.now()
|
for token in tokens:
|
||||||
token.save(update_fields=['date_last_used'])
|
token.date_last_used = timezone.now()
|
||||||
|
token.save(update_fields=['date_last_used'])
|
||||||
|
|
||||||
|
|
||||||
@delay_run(ttl=60)
|
@merge_delay_run(ttl=60)
|
||||||
def update_user_last_used(user):
|
def update_user_last_used(users=()):
|
||||||
user.date_api_key_last_used = timezone.now()
|
for user in users:
|
||||||
user.save(update_fields=['date_api_key_last_used'])
|
user.date_api_key_last_used = timezone.now()
|
||||||
|
user.save(update_fields=['date_api_key_last_used'])
|
||||||
|
|
||||||
|
|
||||||
def after_authenticate_update_date(user, token=None):
|
def after_authenticate_update_date(user, token=None):
|
||||||
update_user_last_used(user)
|
update_user_last_used(users=(user,))
|
||||||
if token:
|
if token:
|
||||||
update_token_last_used(token)
|
update_token_last_used(tokens=(token,))
|
||||||
|
|
||||||
|
|
||||||
class AccessTokenAuthentication(authentication.BaseAuthentication):
|
class AccessTokenAuthentication(authentication.BaseAuthentication):
|
||||||
|
|
|
@ -73,6 +73,7 @@ executor = ThreadPoolExecutor(
|
||||||
)
|
)
|
||||||
_loop_debouncer_func_task_cache = {}
|
_loop_debouncer_func_task_cache = {}
|
||||||
_loop_debouncer_func_args_cache = {}
|
_loop_debouncer_func_args_cache = {}
|
||||||
|
_loop_debouncer_func_task_time_cache = {}
|
||||||
|
|
||||||
|
|
||||||
def get_loop():
|
def get_loop():
|
||||||
|
@ -92,6 +93,17 @@ def cancel_or_remove_debouncer_task(cache_key):
|
||||||
def run_debouncer_func(cache_key, org, ttl, func, *args, **kwargs):
|
def run_debouncer_func(cache_key, org, ttl, func, *args, **kwargs):
|
||||||
cancel_or_remove_debouncer_task(cache_key)
|
cancel_or_remove_debouncer_task(cache_key)
|
||||||
run_func_partial = functools.partial(_run_func_with_org, cache_key, org, func)
|
run_func_partial = functools.partial(_run_func_with_org, cache_key, org, func)
|
||||||
|
|
||||||
|
current = time.time()
|
||||||
|
first_run_time = _loop_debouncer_func_task_time_cache.get(cache_key, None)
|
||||||
|
if first_run_time is None:
|
||||||
|
_loop_debouncer_func_task_time_cache[cache_key] = current
|
||||||
|
first_run_time = current
|
||||||
|
|
||||||
|
if current - first_run_time > ttl:
|
||||||
|
executor.submit(run_func_partial, *args, **kwargs)
|
||||||
|
return
|
||||||
|
|
||||||
loop = _loop_thread.get_loop()
|
loop = _loop_thread.get_loop()
|
||||||
_debouncer = Debouncer(run_func_partial, lambda: True, ttl, loop=loop, executor=executor)
|
_debouncer = Debouncer(run_func_partial, lambda: True, ttl, loop=loop, executor=executor)
|
||||||
task = asyncio.run_coroutine_threadsafe(_debouncer(*args, **kwargs), loop=loop)
|
task = asyncio.run_coroutine_threadsafe(_debouncer(*args, **kwargs), loop=loop)
|
||||||
|
@ -130,6 +142,7 @@ def _run_func_with_org(key, org, func, *args, **kwargs):
|
||||||
logger.error('delay run error: %s' % e)
|
logger.error('delay run error: %s' % e)
|
||||||
_loop_debouncer_func_task_cache.pop(key, None)
|
_loop_debouncer_func_task_cache.pop(key, None)
|
||||||
_loop_debouncer_func_args_cache.pop(key, None)
|
_loop_debouncer_func_args_cache.pop(key, None)
|
||||||
|
_loop_debouncer_func_task_time_cache.pop(key, None)
|
||||||
|
|
||||||
|
|
||||||
def delay_run(ttl=5, key=None):
|
def delay_run(ttl=5, key=None):
|
||||||
|
@ -142,6 +155,9 @@ def delay_run(ttl=5, key=None):
|
||||||
|
|
||||||
def inner(func):
|
def inner(func):
|
||||||
suffix_key_func = key if key else default_suffix_key
|
suffix_key_func = key if key else default_suffix_key
|
||||||
|
sigs = inspect.signature(func)
|
||||||
|
if len(sigs.parameters) != 0:
|
||||||
|
raise ValueError('Merge delay run must not arguments: %s' % func.__name__)
|
||||||
|
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
|
@ -186,12 +202,11 @@ def merge_delay_run(ttl=5, key=None):
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
if not isinstance(v, (tuple, list, set)):
|
if not isinstance(v, (tuple, list, set)):
|
||||||
raise ValueError('func kwargs value must be list or tuple: %s %s' % (func.__name__, v))
|
raise ValueError('func kwargs value must be list or tuple: %s %s' % (func.__name__, v))
|
||||||
|
v = set(v)
|
||||||
if k not in cache_kwargs:
|
if k not in cache_kwargs:
|
||||||
cache_kwargs[k] = v
|
cache_kwargs[k] = v
|
||||||
elif isinstance(v, set):
|
|
||||||
cache_kwargs[k] = cache_kwargs[k].union(v)
|
|
||||||
else:
|
else:
|
||||||
cache_kwargs[k] = list(cache_kwargs[k]) + list(v)
|
cache_kwargs[k] = cache_kwargs[k].union(v)
|
||||||
_loop_debouncer_func_args_cache[cache_key] = cache_kwargs
|
_loop_debouncer_func_args_cache[cache_key] = cache_kwargs
|
||||||
run_debouncer_func(cache_key, org, ttl, func, *args, **cache_kwargs)
|
run_debouncer_func(cache_key, org, ttl, func, *args, **cache_kwargs)
|
||||||
|
|
||||||
|
@ -201,8 +216,8 @@ def merge_delay_run(ttl=5, key=None):
|
||||||
|
|
||||||
|
|
||||||
@delay_run(ttl=5)
|
@delay_run(ttl=5)
|
||||||
def test_delay_run(username):
|
def test_delay_run():
|
||||||
print("Hello, %s, now is %s" % (username, time.time()))
|
print("Hello, now is %s" % time.time())
|
||||||
|
|
||||||
|
|
||||||
@merge_delay_run(ttl=5, key=lambda users=(): users[0][0])
|
@merge_delay_run(ttl=5, key=lambda users=(): users[0][0])
|
||||||
|
|
|
@ -53,7 +53,7 @@ def subscribe_orgs_mapping_expire(sender, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
@delay_run(ttl=5)
|
@delay_run(ttl=5)
|
||||||
def expire_user_orgs(*args):
|
def expire_user_orgs():
|
||||||
User.expire_users_rbac_perms_cache()
|
User.expire_users_rbac_perms_cache()
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue