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 路由时,总是能得到缓存中的数据,而缓存会在后台自动更新,不会因为更新缓存而导致请求超时。


😊

相关推荐
XY.散人4 小时前
初识Redis · C++客户端list和hash
数据库·redis·缓存
·云扬·6 小时前
【技术派后端篇】 Redis 实现用户活跃度排行榜
数据库·redis·缓存
诸葛小猿8 小时前
缓存设计模式
缓存·设计模式
小鱼学习笔记10 小时前
4.17---实现商铺和缓存与数据库双写一致以及宕机处理
数据库·缓存
bing_15813 小时前
相比其他缓存/内存数据库(如 Memcached, Ehcache 等),Redis 在微服务环境中的优势和劣势是什么?
数据库·缓存·memcached·微服务场景
黄名富16 小时前
Redis 缓存—处理高并发问题
数据库·redis·缓存
努力也学不会java1 天前
【Redis】Redis中的常见数据类型(一)
数据结构·数据库·redis·缓存·bootstrap
XY.散人1 天前
初识Redis · 命令、数据结构补充、协议
数据库·redis·缓存
LiuYaoheng1 天前
深入理解Java包装类:自动装箱拆箱与缓存池机制
java·缓存
·云扬·1 天前
【技术派后端篇】Redis实现统计计数
数据库·redis·缓存