经常用lru_cache
来加速一些重复耗时的func
, 今天栽了个坑: func
的缓存在服务热重载后并没有被释放掉, 导致重跑这个方法的时候总是返回旧的数据, 放代码解释:
1
2
3
| @lru_cache()
def parse_file(path):
pass
|
parse_file
接收一个文件路径, 对给定文件做了若干处理, 正常情况是没有问题的, 但是如果文件内容发生了变化, 本例实际上是因为要重跑某些process, 连带着这个文件内容是有更新的, 但是path
不变, 在热重载的时候, 全局缓存并没有清掉, 导致每次调用方法返回的还是旧缓存数据
关于 Tornado 的热重载, 我在这里有过介绍: init_process
问题搞清楚, 解决起来就很简单, 重载的时候清一波就完事
1
2
3
4
5
| def clear_caches():
# All objects cleared
for obj in (i for i in gc.get_objects() if isinstance(i, functools._lru_cache_wrapper)):
obj.cache_clear()
gc.collect()
|
1
2
3
4
5
6
7
8
9
10
11
| class TornadoWorker(Worker):
......
def init_process(self):
# IOLoop cannot survive a fork or be shared across processes
# in any way. When multiple processes are being used, each process
# should create its own IOLoop. We should clear current IOLoop
# if exists before os.fork.
IOLoop.clear_current()
clear_caches()
# You can do something like release db conn/clean fp or else.
super().init_process()
|
然后, 整个世界清净了~
# NOTE: I am not responsible for any expired content.
create@2021-11-09T11:02:12+08:00
update@2021-11-09T11:03:56+08:00
comment@https://github.com/ferstar/blog/issues/48