我在rails项目中遇到缓存方法结果的问题。
我来到这个模拟两个不同请求的代码:
[
Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } },
Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }
]
尝试在rails控制台中执行它。 如果我尝试在控制台中运行它作为输出我得到不同的数字。怎么可能?
但是例如这段代码(带睡眠)按预期工作:
[
Thread.new { sleep(1); puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } },
Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }
]
答案 0 :(得分:1)
在第一段代码中
[
Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } },
Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }
]
我认为您的rails配置正在使用文件进行缓存(为了确保这一点,请检查rails应用程序中的文件夹/ tmp / cache)。
因为' Rails.cache'需要从文件中执行读取缓存,这非常耗时,并且操作提取'在2个主题中大多数是同时运行的,所以' a'价值不存在或已经过期。
在第二段代码中
[
Thread.new { sleep(1); puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } },
Thread.new { puts Rails.cache.fetch('a', expires_in: 2.seconds) { rand } }
]
当第一个帖子尝试获取' a' a' a'已经在缓存文件中。这就是它运作的原因。
让我们进行另一次模拟,而不是使用' Rails.cache',我们将使用这样的MemoryStore缓存:
cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
[
Thread.new { puts cache.fetch('a', expires_in: 2.seconds) { rand } },
Thread.new { puts cache.fetch('a', expires_in: 2.seconds) { rand } }
]
它也符合我们的期望!
答案 1 :(得分:0)
您可以使用互斥锁来防止同时运行某些代码:
mutex = Mutex.new
[ Thread.new { puts mutex.synchronize { Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } }, Thread.new { puts mutex.synchronize { Rails.cache.fetch('a', expires_in: 2.seconds) { rand } } } ]