python3 自动更新的缓存类

这个类会在后台自动更新缓存数据,你只需要调用方法来获取数据即可。


自动更新缓存类

以下是 AutoUpdatingCache 类的实现:

python 复制代码
import threading
import time

class AutoUpdatingCache:
    def __init__(self, update_function, expiry_time=60):
        """
        初始化缓存类。

        :param update_function: 一个函数,用于生成或更新缓存数据。
        :param expiry_time: 缓存的更新周期(秒)。
        """
        self.update_function = update_function
        self.expiry_time = expiry_time
        self.cache_data = None
        self.last_updated = 0
        self.lock = threading.Lock()
        self._start_background_update()

    def _start_background_update(self):
        # 启动后台线程更新缓存
        self.update_thread = threading.Thread(target=self._update_cache_periodically)
        self.update_thread.daemon = True
        self.update_thread.start()

    def _update_cache_periodically(self):
        while True:
            current_time = time.time()
            if current_time - self.last_updated >= self.expiry_time:
                self._update_cache()
            time.sleep(1)  # 每秒检查一次

    def _update_cache(self):
        with self.lock:
            try:
                print("Updating cache...")
                new_data = self.update_function()
                self.cache_data = new_data
                self.last_updated = time.time()
                print("Cache updated!")
            except Exception as e:
                print(f"Error updating cache: {e}")

    def get_data(self):
        with self.lock:
            if self.cache_data is not None:
                return self.cache_data
            else:
                return "Cache is initializing, please try again later."

使用说明

  1. 定义一个数据生成函数

    首先,需要定义一个用于生成或更新缓存数据的函数。这个函数可以是任何耗时的操作,例如从数据库查询、计算复杂结果等。

    python 复制代码
    import time
    
    def generate_cache_data():
        # 模拟耗时操作
        time.sleep(5)
        return {"value": "fresh data", "timestamp": time.time()}
  2. 创建缓存类的实例

    将数据生成函数传递给 AutoUpdatingCache 类,并设置缓存更新周期。

    python 复制代码
    cache = AutoUpdatingCache(update_function=generate_cache_data, expiry_time=30)
  3. 获取缓存数据

    在需要的地方调用 get_data() 方法即可获取缓存数据。

    python 复制代码
    data = cache.get_data()
    print(data)

完整示例

将以上步骤组合起来:

python 复制代码
import threading
import time

class AutoUpdatingCache:
    def __init__(self, update_function, expiry_time=60):
        self.update_function = update_function
        self.expiry_time = expiry_time
        self.cache_data = None
        self.last_updated = 0
        self.lock = threading.Lock()
        self._start_background_update()

    def _start_background_update(self):
        self.update_thread = threading.Thread(target=self._update_cache_periodically)
        self.update_thread.daemon = True
        self.update_thread.start()

    def _update_cache_periodically(self):
        while True:
            current_time = time.time()
            if current_time - self.last_updated >= self.expiry_time:
                self._update_cache()
            time.sleep(1)

    def _update_cache(self):
        with self.lock:
            try:
                print("Updating cache...")
                new_data = self.update_function()
                self.cache_data = new_data
                self.last_updated = time.time()
                print("Cache updated!")
            except Exception as e:
                print(f"Error updating cache: {e}")

    def get_data(self):
        with self.lock:
            if self.cache_data is not None:
                return self.cache_data
            else:
                return "Cache is initializing, please try again later."

# 数据生成函数
def generate_cache_data():
    time.sleep(5)  # 模拟耗时操作
    return {"value": "fresh data", "timestamp": time.time()}

# 创建缓存实例
cache = AutoUpdatingCache(update_function=generate_cache_data, expiry_time=30)

# 模拟获取数据
for _ in range(10):
    data = cache.get_data()
    print(data)
    time.sleep(10)

代码解释

  • AutoUpdatingCache 类

    • init 方法:
      • 初始化缓存,设置数据生成函数和缓存更新周期。
      • 启动后台线程 _update_cache_periodically
    • _update_cache_periodically 方法:
      • 无限循环,每隔一秒检查缓存是否需要更新。
      • 如果当前时间距离上次更新时间超过了 expiry_time,则调用 _update_cache
    • _update_cache 方法:
      • 使用 update_function 更新缓存数据。
      • 使用锁机制 threading.Lock 确保线程安全。
    • get_data 方法:
      • 获取缓存数据。
      • 如果缓存数据为空(初始化中),返回提示信息。
  • 数据生成函数

    • generate_cache_data 函数模拟一个耗时操作,生成新的缓存数据。
  • 使用示例

    • 创建缓存实例并在循环中每隔 10 秒获取一次数据,观察缓存的更新情况。

注意事项

  • 线程安全:

    • 使用 threading.Lock 确保在多线程环境下数据访问的安全性。
  • 异常处理:

    • 在更新缓存时,捕获可能的异常,防止线程崩溃。
  • 后台线程:

    • 将线程设置为守护线程(daemon=True),使得主程序退出时,线程自动结束。

应用场景

你可以将这个缓存类应用在 Web 应用程序中,例如在 Sanic 的路由中:

python 复制代码
from sanic import Sanic
from sanic.response import json

app = Sanic("CacheApp")

@app.route("/data")
async def get_cached_data(request):
    data = cache.get_data()
    return json({"data": data})

if __name__ == "__main__":
    # 确保缓存在应用启动前初始化
    cache = AutoUpdatingCache(update_function=generate_cache_data, expiry_time=30)
    app.run(host="0.0.0.0", port=8000)

这样,用户在访问 /data 路由时,总是能得到缓存中的数据,而缓存会在后台自动更新,不会因为更新缓存而导致请求超时。


😊

相关推荐
SPC的存折5 小时前
1、Redis数据库基础
linux·运维·服务器·数据库·redis·缓存
身如柳絮随风扬12 小时前
Redis如何实现高效插入大量数据
数据库·redis·缓存
予早13 小时前
Redis 设置库的数量
数据库·redis·缓存
黑金IT14 小时前
vLLM本地缓存实战,重复提交直接复用不浪费算力
人工智能·缓存
Rick199315 小时前
Redis查询为什么快
数据库·redis·缓存
Rick199316 小时前
Redis 底层架构图
数据库·redis·缓存
Arva .17 小时前
Redis 数据类型
数据库·redis·缓存
笑我归无处18 小时前
Redis和数据库的数据一致性问题研究
数据库·redis·缓存
小红的布丁18 小时前
操作系统与高性能 IO:零拷贝、一次读 IO、CPU 缓存与伪共享
缓存
SPC的存折19 小时前
(自用)LNMP-Redis-Discuz5.0部署指南-openEuler24.03-测试环境
linux·运维·服务器·数据库·redis·缓存