在 Rails 和 Sinatra 之间通过 memcached 共享数据时,如何修复 Sinatra 不处理 ActiveSupport
when sharing data via memcached between Rails and Sinatra, how fix Sinatra not handling ActiveSupport
有什么方法可以使 Sinatra 透明地正确处理由 Rails 写入的缓存数据,例如,隐式处理 Rails 在存储时使用的 ActiveSupport class数据?
一个 Heroku 托管的 Rails 4 应用程序和一个 Sinatra 应用程序使用共享的 Memcachier 存储来共享某些临时数据。
如果在 Sinatra 上创建 key/value,一切正常:
# on Sinatra:
session.cache.set("foo", "from sinatra", 100)
将设置 Sinatra 应用程序或 Rails 应用程序可以读取的密钥,任何一个应用程序将在 100 秒后过期后自动读取 nil
。 并且Rails和Sinatra都报告数据值的class为字符串。
但是,如果数据由 Rails 应用程序设置:
# on Rails:
Rails.cache.write("foo", "from rails", expires_in: 100)
Rails 应用程序 read
returns 一个字符串(如预期的那样),但是 Sinatra 应用程序 get
returns class 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 应用程序在 到期后获取相同的密钥 ,则返回 相同的 数据(不是零)。
在 Sinatra 应用程序上肯定 可能 使用新方法暴力破解 get
数据,并手动处理过期和数据问题使用 ActiveSupport::Cache::Entry 方法,如下所述。
但似乎应该有某种方法可以让 ActiveSupport::Cache::Entry 代码自动处理这些细节,方法是告诉 Sinatra 将 ActiveSupport::Cache 用于 both设置和获取数据?
# 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,仍然 自动使用 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()
我不是 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")
有什么方法可以使 Sinatra 透明地正确处理由 Rails 写入的缓存数据,例如,隐式处理 Rails 在存储时使用的 ActiveSupport class数据?
一个 Heroku 托管的 Rails 4 应用程序和一个 Sinatra 应用程序使用共享的 Memcachier 存储来共享某些临时数据。
如果在 Sinatra 上创建 key/value,一切正常:
# on Sinatra:
session.cache.set("foo", "from sinatra", 100)
将设置 Sinatra 应用程序或 Rails 应用程序可以读取的密钥,任何一个应用程序将在 100 秒后过期后自动读取 nil
。 并且Rails和Sinatra都报告数据值的class为字符串。
但是,如果数据由 Rails 应用程序设置:
# on Rails:
Rails.cache.write("foo", "from rails", expires_in: 100)
Rails 应用程序 read
returns 一个字符串(如预期的那样),但是 Sinatra 应用程序 get
returns class 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 应用程序在 到期后获取相同的密钥 ,则返回 相同的 数据(不是零)。
在 Sinatra 应用程序上肯定 可能 使用新方法暴力破解 get
数据,并手动处理过期和数据问题使用 ActiveSupport::Cache::Entry 方法,如下所述。
但似乎应该有某种方法可以让 ActiveSupport::Cache::Entry 代码自动处理这些细节,方法是告诉 Sinatra 将 ActiveSupport::Cache 用于 both设置和获取数据?
# 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,仍然 自动使用 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()
我不是 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")