问题描述
是否有任何方法可以使Sinatra正确正确地处理由Rails编写的缓存数据,例如隐式处理Rails在存储数据时使用的ActiveSupport类?
Heroku托管的Rails 4应用程序和Sinatra应用程序使用共享的Memcachier商店共享某些临时数据。
如果在Sinatra上创建了键/值,则一切正常:
# on Sinatra:
session.cache.set("foo","from sinatra",100)
将设置一个Sinatra应用程序或Rails应用程序都可以读取的密钥,并且一旦nil
在100秒后过期,任何一个应用程序都会自动读取。 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应用在到期后 获取了相同的密钥,则会返回 same 数据(不是nil)。
在Sinatra应用程序上可能可以使用get
是数据的新方法对其进行暴力破解,并使用ActiveSupport :: Cache手动处理过期和数据问题:: Entry方法,如下所述。
但是,似乎应该有某种方法可以让ActiveDirect :: 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
目前,根据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,而 still 会自动使用Dalli gem管理与memcachier服务的连接
set :cache,ActiveSupport::Cache::MemCacheStore.new(
... # init parameters
)}
这也意味着使用settings.cache.read/write
方法(与使用Dalli :: Client.new进行配置时使用的settings.cache.get/set
方法相比)。
其他编辑:
在模型内部使用缓存时,无法直接访问settings.cache,需要使用Sinatra :: Application.settings.cache.read()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)