import math from celery.utils.log import get_task_logger from pingcap_sso.celery import app as celery_app from pingcap_sso.models import LarkMessage, User from pingcap_sso.discourse.models import ( DiscourseSingleSignOnRecord ) logger = get_task_logger(__name__) @celery_app.task def check_inconsistency_users_between_sso_asktug(alert_lark_webhook): asktug_user_num = DiscourseSingleSignOnRecord.objects.all().count() chunk_size = 2000 diffs = [] for i in range(math.ceil(asktug_user_num / chunk_size)): asktug_sso_records = DiscourseSingleSignOnRecord.objects.select_related('user').all().order_by('id')[i * chunk_size: (i + 1) * chunk_size] openids = list(asktug_sso_records.values_list('external_id', flat=True)) sso_users = User.objects.filter(openid__in=openids).values_list('openid', 'username') asktug_users = asktug_sso_records.values_list('external_id', 'user__username') diffs += check_inconsistency(sso_users, asktug_users) if diffs: diff_count = len(diffs) if diff_count > 10: diffs = list(diffs)[:10] diffs = '\n'.join([f'{openid} {username}' for openid, username in diffs]) message = f"""**AskTUG & SSO 用户数据不一致** - 数量: {diff_count} 前 10 个: {diffs}""" LarkMessage.send( webhook=alert_lark_webhook, message_type=LarkMessage.MESSAGE_TYPE_MARKDOWN, content=message, remark='AskTUG & SSO 用户数据不一致', _async=False ) def check_inconsistency(sso_users, asktug_users): return set(asktug_users) - set(sso_users)