This commit is contained in:
parent
3f3611592e
commit
b9863631bd
|
@ -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'
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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))
|
Loading…
Reference in New Issue