This commit is contained in:
AKW 2023-12-29 15:12:10 +08:00
parent 3f3611592e
commit b9863631bd
3 changed files with 63 additions and 1 deletions

View File

@ -277,6 +277,7 @@ class JqrKeywordSendGroupMsg(JqrBaseSendMsg):
choices=JqrKeywordSendGroupMsgPatternChoices.choices, choices=JqrKeywordSendGroupMsgPatternChoices.choices,
default=JqrKeywordSendGroupMsgPatternChoices.ANY) default=JqrKeywordSendGroupMsgPatternChoices.ANY)
keyword_text = models.TextField(verbose_name='关键字数组', null=True, blank=True) keyword_text = models.TextField(verbose_name='关键字数组', null=True, blank=True)
priority = models.IntegerField(verbose_name='优先级', default=0)
class Meta: class Meta:
db_table = 'jqr_keywordsendgroupmsg' db_table = 'jqr_keywordsendgroupmsg'

View File

@ -15,6 +15,7 @@ from apps.jqr.models import JqrExternalFollowUser, JqrExternalUser, JqrHookUser
from apps.qc.utils import generate_qrcode_by_qrcode from apps.qc.utils import generate_qrcode_by_qrcode
from apps.warning.models import QcWarningRule, WarningLog, WarningSetting from apps.warning.models import QcWarningRule, WarningLog, WarningSetting
from libs.wechat import WechatWorkerUtil from libs.wechat import WechatWorkerUtil
from utils.redis_lock import SimpleLock
logger = logging.getLogger('apps') logger = logging.getLogger('apps')
@ -87,7 +88,9 @@ def save_add_contact_by_channel(data, corpinfo, *args, **kwargs):
now = datetime.now() now = datetime.now()
nine_minute_ago = now - timedelta(minutes=9) nine_minute_ago = now - timedelta(minutes=9)
uid = hook_user.uid uid = hook_user.uid
if hook_user.utime > nine_minute_ago and hook_user.new_user: rc = SimpleLock(f'{corpid}:{userid}:{externaluserid}')
success = rc.try_lock(60 * 10)
if hook_user.utime > nine_minute_ago and hook_user.new_user and success:
# 发送消息 # 发送消息
send_new_user_msg(corpid, userid, externaluserid, uid=uid) send_new_user_msg(corpid, userid, externaluserid, uid=uid)

58
utils/redis_lock.py Normal file
View File

@ -0,0 +1,58 @@
import uuid
from abc import ABC, abstractmethod
from threading import current_thread
from django_redis import get_redis_connection
import logging
logger = logging.getLogger('apps')
class ILock(ABC):
@abstractmethod
def try_lock(self, timeout: int) -> bool:
pass
@abstractmethod
def unlock(self) -> None:
pass
class SimpleLock(ILock):
KEY_PREFIX = "lock:"
# ID_PREFIX = str(uuid.uuid4()).replace("-", '') + "-"
ID_PREFIX = '-'
def __init__(self, name: str, alias: str = "default") -> None:
self.name = name
self.redis_con = get_redis_connection(alias)
self.key = f"{self.KEY_PREFIX}{self.ID_PREFIX}"
def try_lock(self, timeout: int) -> bool:
current_thread_id, value = self.get_value()
logger.info(f"线程:{current_thread_id}开始获取锁")
is_locked = self.set_if_absent(self.key, value, timeout)
logger.info(f"线程:{current_thread_id}获取锁是否成功: {bool(is_locked)}")
return bool(is_locked)
def get_value(self) -> tuple:
current_thread_id = current_thread().ident
value = f"{self.ID_PREFIX}{current_thread_id}"
return current_thread_id, value
def unlock(self) -> None:
current_thread_id, value = self.get_value()
logger.info(f"线程:{current_thread_id}开始删除锁")
lua_script = """if (redis.call('get', KEYS[1]) == ARGV[1]) then
-- 释放锁 del key
return redis.call('del', KEYS[1])
end
return 0
"""
deleted = self.redis_con.eval(lua_script, 1, self.key, value)
logger.info(f"线程:{current_thread_id}删除锁是否成功: {bool(deleted)}")
def set_if_absent(self, key: str, value: str, timeout: int) -> bool:
return bool(self.redis_con.set(key, value, ex=timeout, nx=True))