我很容易被问到: 让我的佣金任务是:
namespace :common do
desc 'check rails cache'
task easy_task: :environment do
l = -> (test_param) do
puts "cache value isn't found, reload..."
'this is result'
end
result = Rails.cache.fetch('test_task', expires_in: 1.hour) do
l.call(1)
end
end
end
我的期望 - 输出短语"缓存值未找到,重新加载......"将仅输出rake common:easy_task
的第一次运行,但每次运行都会输出。
另外,我试试:
rake common:easy_task
rails common:easy_task
bundle exec spring rake common:easy_task
bundle exec spring rails common:easy_task
也不是这些帮助。
Rails缓存不在rake任务中工作,但在控制台和App中工作。为什么呢?
答案 0 :(得分:1)
如果在控制台中有效但在rake任务中没有,你可能正在使用ActiveSupport::Cache::MemoryStore(这是 config / environments / development.rb 中的默认值,如果你有临时文件来启用缓存,否则它使用ActiveSupport::Cache::NullStore,由于显而易见的原因无法在任何地方工作),它将事物存储在进程内存中:
缓存存储实现,它在同一进程中将所有内容存储到内存中。
Rails.configuration.cache_store # => :memory_store
l = -> (test_param) do
puts "cache value isn't found, reload..."
'this is result'
end
Rails.cache.fetch('test_task', expires_in: 1.hour) do
l.call(1)
end
# cache value isn't found, reload...
# => "this is result"
Rails.cache.fetch('test_task', expires_in: 1.hour) do
l.call(1)
end
# => "this is result"
但是在rake任务中也不会起作用,每次使用一个单独的进程
$ rake common:easy_task
# [:memory_store, "pid = 26230"]
# cache value isn't found, reload...
$ rake common:easy_task
# [:memory_store, "pid = 26253"]
# cache value isn't found, reload...
即使使用弹簧,每次运行的过程都是不同的
$ bin/rake common:easy_task
# Running via Spring preloader in process 26283
# [:memory_store, "pid = 26283"]
# cache value isn't found, reload...
$ bin/rake common:easy_task
# Running via Spring preloader in process 26297
# [:memory_store, "pid = 26297"]
# cache value isn't found, reload...
要解决这个问题,我们需要使用不同的内存存储(我将在此示例中使用ActiveSupport::Cache::FileStore,但请使用您喜欢的其他内容)
config.cache_store = :file_store, Rails.root.join('tmp/cache_store')
然后rake任务按预期工作:
$ bin/rake common:easy_task
# Running via Spring preloader in process 26400
# [:file_store, #<Pathname:.../tmp/cache_store>, "pid = 26400"]
# cache value isn't found, reload...
$ bin/rake common:easy_task
# Running via Spring preloader in process 26414
# [:file_store, #<Pathname:.../tmp/cache_store>, "pid = 26414"]
$ bin/rails c
# Running via Spring preloader in process 26430
result = Rails.cache.fetch('test_task', expires_in: 1.hour) do
l.call(1)
end
# => "this is result"