This is the 22nd day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
Hello ~ I’m Milo! I am building an open source interface testing platform from 0 to 1, and I am also writing a complete tutorial corresponding to it. I hope you can support it. Welcome to pay attention to my public number test development pit goods, get the latest article tutorial!
review
In the last section, we made pre-conditional replication available. This section is supposed to be about sending emails.
But before I do, I have a very serious question.
configuration
Our test platform will be connected to YAPI and other systems in the future. There has to be a place to maintain the data.
Including sender email, password, and so on.
However, these data are usually shared globally. If put in DB, it is useless, because there is only one data. If put in Redis, the data may be lost.
The blogger wasn’t sure where to put it and decided to put it in a configuration.json configuration file.
But it’s not good to read files too often. In addition, there will be many workers online, and there may be conflicts.
Think of the redis we used before, isn’t that where it comes in?
Write generic cache methods
Before we do that, let’s think about why we wrote this generic caching approach:
We get the data in two parts, get and set. In combination with caching, we can write pseudocode like this:
def get_cache() :
data = redis.get(key)
if data is not None:
return data
data = get_data()
redis.set(key, data)
return data
Copy the code
If we get the key, we return, if we don’t get the key, we update the data, we write the data to Redis, and we return data.
So what do we do when we modify the data?
def update_cache() :
update(data)
redis.delete(key)
Copy the code
- Update the data source first
- Delete cached data so that when you go down to fetch the cache
Retrieve data
And write to the cache
But do you think that this is a tedious process, and it’s something other than get and set, and every time we do that, we can decorateit.
Write the cache decorator
-
Method to connect to local Redis
First we configure the connection information of Redis in config.py, then we write the client client, because it is the connection pool mode, so we have no problem using this client. (So I’m going to set it to property here)
-
Write RedisHelper
The helper class has two decorators: cache reads (get) and up_cache updates (set).
class RedisHelper(object) :
pity_prefix = "pity"
pity_redis_client = PityRedisManager().client
@staticmethod
def get_key(key: str) :
return f"{RedisHelper.pity_prefix}:{key}"
@staticmethod
def cache(key: str, expired_time=3 * 60) :
Automatic cache decorator :param key: cached key: param expired_time: default key expiration time: return: """
def decorator(func) :
@functools.wraps(func)
def wrapper(*args, **kwargs) :
redis_key = RedisHelper.get_key(key)
data = RedisHelper.pity_redis_client.get(redis_key)
The cache already exists
if data is not None:
return json.loads(data)
Get the latest data
new_data = func(*args, **kwargs)
info = json.dumps(new_data)
RedisHelper.pity_redis_client.set(redis_key, info, ex=expired_time)
return new_data
return wrapper
return decorator
@staticmethod
def up_cache(key: str) :
Param key: :return: """
def decorator(func) :
@functools.wraps(func)
def wrapper(*args, **kwargs) :
redis_key = RedisHelper.get_key(key)
Get the latest data
new_data = func(*args, **kwargs)
Update data, delete cache
RedisHelper.pity_redis_client.delete(redis_key)
return new_data
return wrapper
return decorator
Copy the code
Here we basically according to the logic said before to do, in the future we fetch data method, just need to + the cache decorator in front of the method, can automatically get through with Redis. (Cache data if there is cache, real data if there is no cache)
Write a method for obtaining configuration files
We write configuration.json to the root directory:
import json
import os
from app.middleware.RedisManager import RedisHelper
from config import Config
class SystemConfiguration(object) :
"" system Configuration ""
@staticmethod
@RedisHelper.cache("configuration".24 * 3600)
def get_config() :
try:
filepath = os.path.join(Config.ROOT, "configuration.json")
if not os.path.exists(filepath):
raise Exception("Configuration file not found, please check if configuration file has been deleted.")
with open(filepath, mode="r", encoding='utf-8') as f:
return json.load(f)
except Exception as e:
raise Exception(F "Failed to obtain system Settings,{e}")
@staticmethod
@RedisHelper.up_cache("configuration")
def update_config(config) :
try:
filepath = os.path.join(Config.ROOT, "configuration.json")
if not os.path.exists(filepath):
raise Exception("Configuration file not found, please check if configuration file has been deleted.")
with open(filepath, mode="r", encoding='utf-8') as f:
json.dump(config, f)
except Exception as e:
raise Exception(F "Failed to update system Settings,{e}")
Copy the code
Since configuration files are rarely updated, we set the expiration of the key to one day (it could be much longer).
This way, we can call get_config to get the system Settings, which contain our important sender information.
Test the
After starting the program, we go to query the key about configuration in Redis, and use our own client:
Test the expiration time again:
That’s it for today. Next, we’ll start our inspirational email (report notification) tour.