是否有任何方法可以使 Sinatra 透明地正确处理由 Rails 编写的缓存数据,例如,隐式处理 Rails 在存储数据时使用的 ActiveSupport 类?
Heroku 托管的 Rails 4 应用程序和 Sinatra 应用程序使用共享的 Memcachier 存储来共享某些临时数据。
如果在 Sinatra 上创建了键/值,则一切正常:
# on Sinatra:
session.cache.set("foo", "from sinatra", 100)
将设置一个Sinatra应用程序或Rails应用程序可以读取的 key ,并且一旦它在100秒内过期,任何一个应用程序都会自动读取nil
。 Rails 和 Sinatra 都将数据值的类报告为 String。
但是,如果数据是由 Rails 应用程序设置的:
# on Rails:
Rails.cache.write("foo", "from rails", expires_in: 100)
Rails 应用程序 read
返回一个字符串(如预期),但 Sinatra 应用程序 get
返回类 ActiveSupport::Cache::Entry
# on Sinatra
d = settings.cache.get("foo")
=> #<ActiveSupport::Cache::Entry:0x7f7ea70 @value="from rails", @created_at=1598330468.8312092, @expires_in=100.0>
如果 Sinatra 应用在过期后获取相同的 key ,则返回相同数据(不是零)。
在 Sinatra 应用程序上当然可以使用一种新方法来暴力破解它,获取
数据,并使用 ActiveSupport 手动处理过期和数据问题::Cache::Entry 方法,如下所述。
但似乎应该有某种方法让 ActiveSupport::Cache::Entry 代码自动处理这些细节,告诉 Sinatra 使用 ActiveSupport::Cache 进行设置和获取数据。 ?
# pseudo code for Sinatra app
def new_get(key)
x = settings.cache.get(key)
if x.class == ActiveSupport::Cache::Entry
if x.expired?
x.delete
return nil
else return x.value
else return x
end
目前,memcache 存储是根据 Heroku 在线文档配置的:
require 'dalli'
set :cache, Dalli::Client.new(
(ENV["MEMCACHIER_SERVERS"] || "").split(","),
{:username => ENV["MEMCACHIER_USERNAME"],
:password => ENV["MEMCACHIER_PASSWORD"],
:failover => true, # default is true
:socket_timeout => 1.5, # default is 0.5
:socket_failure_delay => 0.2, # default is 0.01
:down_retry_delay => 60 # default is 60
})
编辑 - 已解决 根据接受的答案,Sinatra/Rails 数据互操作性的关键是显式配置缓存存储以使用 ActiveSupport,它仍然自动使用 Dalli gem 来管理与 memcachier 服务的连接.
set :cache, ActiveSupport::Cache::MemCacheStore.new(
... # init parameters
)}
这也意味着使用 settings.cache.read/write
方法(与使用 Dalli::Client 配置时使用的 settings.cache.get/set
方法相比) .新)。
额外编辑:
在模型内部使用缓存时,无法直接访问settings.cache,需要使用Sinatra::Application.settings.cache.read()
最佳答案
我不是 Sinatra 用户,在 Rails 中使用过类似下面的内容。
cache_store = ActiveSupport::Cache::MemCacheStore.new('localhost')
# For writing the keys:
cache_store.write("foo", "from rails", expires_in: 100)
# For reading the keys
cache_store.read("foo")
编辑
看来您正在使用 gem dalli ,您还可以使用 DalliStore
代替 MemCacheStore
,如下所示:
cache_store = ActiveSupport::Cache::DalliStore.new('localhost')
# For writing the keys:
cache_store.write("foo", "from rails", expires_in: 100)
# For reading the keys
cache_store.read("foo")
关于ruby-on-rails - 当 Rails 和 Sinatra 之间通过 memcached 共享数据时,如何修复 Sinatra 不处理 ActiveSupport,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63572308/