在Rails和Sinatra之间通过memcached共享数据时,如何解决Sinatra不处理ActiveSupport

问题描述

是否有任何方法可以使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 (将#修改为@)