mirror of https://github.com/jumpserver/jumpserver
perf: 优化授权树的刷新,同步解决同步异步的问题
parent
f5802ace02
commit
0303408be8
|
@ -63,7 +63,7 @@ def create_accounts_activities(account, action='create'):
|
||||||
def on_account_create_by_template(sender, instance, created=False, **kwargs):
|
def on_account_create_by_template(sender, instance, created=False, **kwargs):
|
||||||
if not created or instance.source != 'template':
|
if not created or instance.source != 'template':
|
||||||
return
|
return
|
||||||
push_accounts_if_need(accounts=(instance,))
|
push_accounts_if_need.delay(accounts=(instance,))
|
||||||
create_accounts_activities(instance, action='create')
|
create_accounts_activities(instance, action='create')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,13 +63,13 @@ def on_asset_create(sender, instance=None, created=False, **kwargs):
|
||||||
return
|
return
|
||||||
logger.info("Asset create signal recv: {}".format(instance))
|
logger.info("Asset create signal recv: {}".format(instance))
|
||||||
|
|
||||||
ensure_asset_has_node(assets=(instance,))
|
ensure_asset_has_node.delay(assets=(instance,))
|
||||||
|
|
||||||
# 获取资产硬件信息
|
# 获取资产硬件信息
|
||||||
auto_config = instance.auto_config
|
auto_config = instance.auto_config
|
||||||
if auto_config.get('ping_enabled'):
|
if auto_config.get('ping_enabled'):
|
||||||
logger.debug('Asset {} ping enabled, test connectivity'.format(instance.name))
|
logger.debug('Asset {} ping enabled, test connectivity'.format(instance.name))
|
||||||
test_assets_connectivity_handler(assets=(instance,))
|
test_assets_connectivity_handler.delay(assets=(instance,))
|
||||||
if auto_config.get('gather_facts_enabled'):
|
if auto_config.get('gather_facts_enabled'):
|
||||||
logger.debug('Asset {} gather facts enabled, gather facts'.format(instance.name))
|
logger.debug('Asset {} gather facts enabled, gather facts'.format(instance.name))
|
||||||
gather_assets_facts_handler(assets=(instance,))
|
gather_assets_facts_handler(assets=(instance,))
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
#
|
#
|
||||||
from operator import add, sub
|
from operator import add, sub
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.db.models.signals import m2m_changed
|
from django.db.models.signals import m2m_changed
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from assets.models import Asset, Node
|
from assets.models import Asset, Node
|
||||||
from common.const.signals import PRE_CLEAR, POST_ADD, PRE_REMOVE
|
from common.const.signals import PRE_CLEAR, POST_ADD, PRE_REMOVE
|
||||||
from common.decorators import on_transaction_commit, merge_delay_run
|
from common.decorators import on_transaction_commit, merge_delay_run
|
||||||
|
from common.signals import django_ready
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from orgs.utils import tmp_to_org
|
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||||
from ..tasks import check_node_assets_amount_task
|
from ..tasks import check_node_assets_amount_task
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
@ -34,7 +36,7 @@ def on_node_asset_change(sender, action, instance, reverse, pk_set, **kwargs):
|
||||||
node_ids = [instance.id]
|
node_ids = [instance.id]
|
||||||
else:
|
else:
|
||||||
node_ids = list(pk_set)
|
node_ids = list(pk_set)
|
||||||
update_nodes_assets_amount(node_ids=node_ids)
|
update_nodes_assets_amount.delay(node_ids=node_ids)
|
||||||
|
|
||||||
|
|
||||||
@merge_delay_run(ttl=30)
|
@merge_delay_run(ttl=30)
|
||||||
|
@ -52,3 +54,18 @@ def update_nodes_assets_amount(node_ids=()):
|
||||||
node.assets_amount = node.get_assets_amount()
|
node.assets_amount = node.get_assets_amount()
|
||||||
|
|
||||||
Node.objects.bulk_update(nodes, ['assets_amount'])
|
Node.objects.bulk_update(nodes, ['assets_amount'])
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(django_ready)
|
||||||
|
def set_assets_size_to_setting(sender, **kwargs):
|
||||||
|
from assets.models import Asset
|
||||||
|
try:
|
||||||
|
with tmp_to_root_org():
|
||||||
|
amount = Asset.objects.order_by().count()
|
||||||
|
except:
|
||||||
|
amount = 0
|
||||||
|
|
||||||
|
if amount > 20000:
|
||||||
|
settings.ASSET_SIZE = 'large'
|
||||||
|
elif amount > 2000:
|
||||||
|
settings.ASSET_SIZE = 'medium'
|
||||||
|
|
|
@ -44,18 +44,18 @@ def on_node_post_create(sender, instance, created, update_fields, **kwargs):
|
||||||
need_expire = False
|
need_expire = False
|
||||||
|
|
||||||
if need_expire:
|
if need_expire:
|
||||||
expire_node_assets_mapping(org_ids=(instance.org_id,))
|
expire_node_assets_mapping.delay(org_ids=(instance.org_id,))
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=Node)
|
@receiver(post_delete, sender=Node)
|
||||||
def on_node_post_delete(sender, instance, **kwargs):
|
def on_node_post_delete(sender, instance, **kwargs):
|
||||||
expire_node_assets_mapping(org_ids=(instance.org_id,))
|
expire_node_assets_mapping.delay(org_ids=(instance.org_id,))
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=Asset.nodes.through)
|
@receiver(m2m_changed, sender=Asset.nodes.through)
|
||||||
def on_node_asset_change(sender, instance, action='pre_remove', **kwargs):
|
def on_node_asset_change(sender, instance, action='pre_remove', **kwargs):
|
||||||
if action.startswith('post'):
|
if action.startswith('post'):
|
||||||
expire_node_assets_mapping(org_ids=(instance.org_id,))
|
expire_node_assets_mapping.delay(org_ids=(instance.org_id,))
|
||||||
|
|
||||||
|
|
||||||
@receiver(django_ready)
|
@receiver(django_ready)
|
||||||
|
|
|
@ -34,9 +34,9 @@ def update_user_last_used(users=()):
|
||||||
|
|
||||||
|
|
||||||
def after_authenticate_update_date(user, token=None):
|
def after_authenticate_update_date(user, token=None):
|
||||||
update_user_last_used(users=(user.id,))
|
update_user_last_used.delay(users=(user.id,))
|
||||||
if token:
|
if token:
|
||||||
update_token_last_used(tokens=(token,))
|
update_token_last_used.delay(tokens=(token,))
|
||||||
|
|
||||||
|
|
||||||
class AccessTokenAuthentication(authentication.BaseAuthentication):
|
class AccessTokenAuthentication(authentication.BaseAuthentication):
|
||||||
|
|
|
@ -199,18 +199,9 @@ def merge_delay_run(ttl=5, key=None):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def inner(func):
|
def delay(func, *args, **kwargs):
|
||||||
sigs = inspect.signature(func)
|
|
||||||
if len(sigs.parameters) != 1:
|
|
||||||
raise ValueError('func must have one arguments: %s' % func.__name__)
|
|
||||||
param = list(sigs.parameters.values())[0]
|
|
||||||
if not isinstance(param.default, tuple):
|
|
||||||
raise ValueError('func default must be tuple: %s' % param.default)
|
|
||||||
suffix_key_func = key if key else default_suffix_key
|
|
||||||
|
|
||||||
@functools.wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
from orgs.utils import get_current_org
|
from orgs.utils import get_current_org
|
||||||
|
suffix_key_func = key if key else default_suffix_key
|
||||||
org = get_current_org()
|
org = get_current_org()
|
||||||
func_name = f'{func.__module__}_{func.__name__}'
|
func_name = f'{func.__module__}_{func.__name__}'
|
||||||
key_suffix = suffix_key_func(*args, **kwargs)
|
key_suffix = suffix_key_func(*args, **kwargs)
|
||||||
|
@ -228,6 +219,26 @@ def merge_delay_run(ttl=5, key=None):
|
||||||
_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)
|
||||||
|
|
||||||
|
def apply(func, sync=False, *args, **kwargs):
|
||||||
|
if sync:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
else:
|
||||||
|
return delay(func, *args, **kwargs)
|
||||||
|
|
||||||
|
def inner(func):
|
||||||
|
sigs = inspect.signature(func)
|
||||||
|
if len(sigs.parameters) != 1:
|
||||||
|
raise ValueError('func must have one arguments: %s' % func.__name__)
|
||||||
|
param = list(sigs.parameters.values())[0]
|
||||||
|
if not isinstance(param.default, tuple):
|
||||||
|
raise ValueError('func default must be tuple: %s' % param.default)
|
||||||
|
func.delay = functools.partial(delay, func)
|
||||||
|
func.apply = functools.partial(apply, func)
|
||||||
|
|
||||||
|
@functools.wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
|
@ -214,6 +214,9 @@ PERM_TREE_REGEN_INTERVAL = CONFIG.PERM_TREE_REGEN_INTERVAL
|
||||||
MAGNUS_ORACLE_PORTS = CONFIG.MAGNUS_ORACLE_PORTS
|
MAGNUS_ORACLE_PORTS = CONFIG.MAGNUS_ORACLE_PORTS
|
||||||
LIMIT_SUPER_PRIV = CONFIG.LIMIT_SUPER_PRIV
|
LIMIT_SUPER_PRIV = CONFIG.LIMIT_SUPER_PRIV
|
||||||
|
|
||||||
|
# Asset account may be too many
|
||||||
|
ASSET_SIZE = 'small'
|
||||||
|
|
||||||
# Chat AI
|
# Chat AI
|
||||||
CHAT_AI_ENABLED = CONFIG.CHAT_AI_ENABLED
|
CHAT_AI_ENABLED = CONFIG.CHAT_AI_ENABLED
|
||||||
GPT_API_KEY = CONFIG.GPT_API_KEY
|
GPT_API_KEY = CONFIG.GPT_API_KEY
|
||||||
|
|
|
@ -87,7 +87,7 @@ class OrgResourceStatisticsRefreshUtil:
|
||||||
if not cache_field_name:
|
if not cache_field_name:
|
||||||
return
|
return
|
||||||
org = getattr(instance, 'org', None)
|
org = getattr(instance, 'org', None)
|
||||||
cls.refresh_org_fields(((org, cache_field_name),))
|
cls.refresh_org_fields.delay(org_fields=((org, cache_field_name),))
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save)
|
@receiver(post_save)
|
||||||
|
|
|
@ -72,7 +72,7 @@ class UserPermTreeRefreshUtil(_UserPermTreeCacheMixin):
|
||||||
|
|
||||||
@timeit
|
@timeit
|
||||||
def refresh_if_need(self, force=False):
|
def refresh_if_need(self, force=False):
|
||||||
built_just_now = cache.get(self.cache_key_time)
|
built_just_now = False if settings.ASSET_SIZE == 'small' else cache.get(self.cache_key_time)
|
||||||
if built_just_now:
|
if built_just_now:
|
||||||
logger.info('Refresh user perm tree just now, pass: {}'.format(built_just_now))
|
logger.info('Refresh user perm tree just now, pass: {}'.format(built_just_now))
|
||||||
return
|
return
|
||||||
|
@ -80,12 +80,18 @@ class UserPermTreeRefreshUtil(_UserPermTreeCacheMixin):
|
||||||
if not to_refresh_orgs:
|
if not to_refresh_orgs:
|
||||||
logger.info('Not have to refresh orgs')
|
logger.info('Not have to refresh orgs')
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info("Delay refresh user orgs: {} {}".format(self.user, [o.name for o in to_refresh_orgs]))
|
logger.info("Delay refresh user orgs: {} {}".format(self.user, [o.name for o in to_refresh_orgs]))
|
||||||
refresh_user_orgs_perm_tree(user_orgs=((self.user, tuple(to_refresh_orgs)),))
|
sync = True if settings.ASSET_SIZE == 'small' else False
|
||||||
refresh_user_favorite_assets(users=(self.user,))
|
refresh_user_orgs_perm_tree.apply(sync=sync, user_orgs=((self.user, tuple(to_refresh_orgs)),))
|
||||||
|
refresh_user_favorite_assets.apply(sync=sync, users=(self.user,))
|
||||||
|
|
||||||
@timeit
|
@timeit
|
||||||
def refresh_tree_manual(self):
|
def refresh_tree_manual(self):
|
||||||
|
"""
|
||||||
|
用来手动 debug
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
built_just_now = cache.get(self.cache_key_time)
|
built_just_now = cache.get(self.cache_key_time)
|
||||||
if built_just_now:
|
if built_just_now:
|
||||||
logger.info('Refresh just now, pass: {}'.format(built_just_now))
|
logger.info('Refresh just now, pass: {}'.format(built_just_now))
|
||||||
|
@ -105,6 +111,7 @@ class UserPermTreeRefreshUtil(_UserPermTreeCacheMixin):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._clean_user_perm_tree_for_legacy_org()
|
self._clean_user_perm_tree_for_legacy_org()
|
||||||
|
if settings.ASSET_SIZE != 'small':
|
||||||
ttl = settings.PERM_TREE_REGEN_INTERVAL
|
ttl = settings.PERM_TREE_REGEN_INTERVAL
|
||||||
cache.set(self.cache_key_time, int(time.time()), ttl)
|
cache.set(self.cache_key_time, int(time.time()), ttl)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue