Python给接口加一个装饰器:登记操作记录、接口加锁
1. 登记操作记录:将用户信息、uri、提交的信息存储在数据库
2. 接口加锁:将接口及携带的信息缓存到redis中,访问这个接口时,若接口响应慢,只有等接口响应完后,才可以再次访问接口
一:登记操作记录
1. modul层
class UserOperateRecordModel(BaseModel):
"""用户表"""
class Meta:
db_table = "user_operate_record"
id = AutoField(primary_key=True)
userid = CharField(verbose_name='用户ID', null=False, default="")
method = CharField(verbose_name='请求方式', null=False, default="")
uri = CharField(verbose_name='操作uri', null=False, default="")
params = JSONCharField(verbose_name='操作参数', null=False, default="")
update_time = DateTimeField(verbose_name="更新时间")
create_time = DateTimeField(verbose_name="创建时间", null=False, default=datetime.datetime.now)
2. 装饰器层
def operate_record(func):
"""登记操作记录"""
@functools.wraps(func)
def _wrapper(handler, *args, **kwargs):
uri = handler.request.path
method = handler.request.method
userid = handler.task_node.userid or ""
params = handler.json_param
try:
UserOperateRecordModel.\
create(userid=userid,
method=method,
uri=uri,
params=params,
)
except:
raise HaomoError(1, '登记操作记录失败')
return func(handler, *args, **kwargs)
return _wrapper
3. handler层
from common.decorations import locker, operate_record
class TaskHandler(TaskBaseHandler):
@operate_record
@locker(key_str="mc_task_modify:{task_id}",
key_args=[("task_id", "self", lambda x: x.get_param("task_id", 0))],
expire=10)
def put(self):
"""修改任务配置"""
task_id = self.get_param('task_id', 0)
task_type = self.get_param('task_type', '')
visual_type = self.get_param('visual_type', '')
if not all((task_id, task_type, visual_type)):
raise HaomoError(1, '参数不合法')
if task_type not in DIST_CONFIG.task_type.values:
raise HaomoError(1, '任务类型不合法')
task_type = DIST_CONFIG.task_type[task_type]
# 查询总任务记录
task_srv = TaskService.get_by_id(task_id)
if not task_srv:
raise HaomoError(1, '总任务不存在')
# 修改总任务对应的字段
task_srv.update(task_type=task_type, visual_type=visual_type)
二、 接口响应加锁
1. 装饰器层
def locker(key_str, key_args=None, expire=3, is_raise=True):
"""redis locker"""
def _cache(fn):
@functools.wraps(fn)
def _wrap(*args, **kwargs):
argvalues = inspect.getcallargs(fn, *args, **kwargs)
cache_key = HMCache.get_cache_key(key_str, key_args, argvalues)
rd = RedisConnector.get("redis")
# 设置锁
if not rd.set(cache_key, 1, ex=expire, nx=True):
gen_log.info("获取锁失败 key=%s", cache_key)
if is_raise:
raise HaomoError(-1, "获取锁失败", cache_key=cache_key)
return False
try:
# 执行函数
if args and kwargs:
return fn(*args, **kwargs)
elif args and not kwargs:
return fn(*args)
elif not args and kwargs:
return fn(**kwargs)
else:
return fn()
except HaomoError as he:
raise he
finally:
# 释放锁
rd.delete(cache_key)
return _wrap
return _cache
2. handler层
from common.decorations import locker, operate_record
class TaskHandler(TaskBaseHandler):
@operate_record
@locker(key_str="mc_task_modify:{task_id}",
key_args=[("task_id", "self", lambda x: x.get_param("task_id", 0))],
expire=10)
def put(self):
"""修改任务配置"""
task_id = self.get_param('task_id', 0)
task_type = self.get_param('task_type', '')
visual_type = self.get_param('visual_type', '')
if not all((task_id, task_type, visual_type)):
raise HaomoError(1, '参数不合法')
if task_type not in DIST_CONFIG.task_type.values:
raise HaomoError(1, '任务类型不合法')
task_type = DIST_CONFIG.task_type[task_type]
# 查询总任务记录
task_srv = TaskService.get_by_id(task_id)
if not task_srv:
raise HaomoError(1, '总任务不存在')
# 修改总任务对应的字段
task_srv.update(task_type=task_type, visual_type=visual_type)