import os
from flask_apscheduler import APScheduler
from flask_script import Manager
from redis import ConnectionPool
from app import create_app
# app = create_app(os.environ.get('futures') or 'default')
app = create_app(os.environ.get('futures') or 'testing')
manager = Manager(app)
# scheduler = APScheduler()
host = app.config['REDIS_HOST']
port = app.config['REDIS_PORT']
db = app.config['REDIS_DB']
redis_pool = ConnectionPool(host=host, port=port, db=db)
if __name__ == '__main__':
# scheduler.init_app(app)
# scheduler.start()
manager.run()
import pickle
import time
import redis
from flask import current_app
from manage import redis_pool
def lock_redis_get(func):
""" 裝飾器:給redis的get方法人爲加鎖 """
def inner(cls, key):
a = func(cls, key)
if a:
print(key, "直接查詢成功")
return a
else:
flag_key = key + "flag"
flag = MyRedis.get_eval(flag_key)
if flag:
while True:
print(key, "已經有其他線程在寫入")
time.sleep(0.5)
a = func(cls, key)
if a:
print(key, "等待查詢成功")
return a
else:
MyRedis.set(flag_key, True)
return func(cls, key)
return inner
class MyRedis(object):
"""
redis數據庫操作
"""
@staticmethod
def _get_r():
redis_instance = redis.StrictRedis(connection_pool=redis_pool)
return redis_instance
@classmethod
def set(cls, key, value, expire=None):
"""
寫入鍵值對
"""
# 判斷是否有過期時間,沒有就設置默認值
if expire:
expire_in_seconds = expire
else:
expire_in_seconds = current_app.config['REDIS_EXPIRE']
r = cls._get_r()
# value = pickle.dumps(value)
r.set(key, value, ex=expire_in_seconds)
@classmethod
# @lock_redis_get
def get(cls, key):
"""
讀取鍵值對內容
"""
r = cls._get_r()
value = r.get(key)
return value.decode('utf-8') if value else value
# return pickle.loads(value)
@classmethod
def lock_get(cls, key):
"""
加鎖讀取鍵值對內容
"""
r = cls._get_r()
value = r.get(key)
if value:
return value.decode('utf-8')
else:
flag_key = key + "flag"
flag = cls.get_eval(flag_key)
if flag:
while True:
print(key, "已經有其他線程在寫入")
time.sleep(0.5)
value = r.get(key)
if value:
print(key, "等待查詢成功")
return value.decode('utf-8')
else:
cls.set(flag_key, True)
@classmethod
def get_eval(cls, key):
"""
讀取鍵值對內容
"""
r = cls._get_r()
value = r.get(key)
val = value.decode('utf-8') if value else value
try:
re_val = eval(val)
return re_val
except Exception as e:
return val
@classmethod
def hset(cls, name, key, value):
"""
寫入hash表
"""
r = cls._get_r()
r.hset(name, key, value)
@classmethod
def hmset(cls, key, *value):
"""
讀取指定hash表的所有給定字段的值
"""
r = cls._get_r()
value = r.hmset(key, *value)
return value
@classmethod
def hget(cls, name, key):
"""
讀取指定hash表的鍵值
"""
r = cls._get_r()
value = r.hget(name, key)
return value.decode('utf-8') if value else value
@classmethod
def hgetall(cls, name):
"""
獲取指定hash表所有的值
"""
r = cls._get_r()
return r.hgetall(name)
@classmethod
def keys(cls, pattern='*'):
"""
獲取匹配到的鍵列表
"""
r = cls._get_r()
return r.keys(pattern)
@classmethod
def delete(cls, *names):
"""
刪除一個或者多個
"""
r = cls._get_r()
r.delete(*names)
@classmethod
def hdel(cls, name, key):
"""
刪除指定hash表的鍵值
"""
r = cls._get_r()
r.hdel(name, key)
@classmethod
def exists(cls, name):
"""
判斷redis中是否存在某個key
"""
r = cls._get_r()
return r.execute_command('EXISTS', name)
@classmethod
def expire(cls, name, expire=None):
"""
設置過期時間
"""
if expire:
expire_in_seconds = expire
else:
expire_in_seconds = current_app.config['REDIS_EXPIRE']
r = cls._get_r()
r.expire(name, expire_in_seconds)