Issue
Is there any way to cause Sinatra to transparently handle cached data correctly that was written by Rails, eg, to implicitly handle the ActiveSupport class that Rails uses when it stores data?
A Heroku-hosted Rails 4 app and a Sinatra app used a shared Memcachier store to share certain ephemeral data.
If a key/value is created on Sinatra, everything works normally:
# on Sinatra:
session.cache.set("foo", "from sinatra", 100)
will set a key that either the Sinatra app or the Rails app can read, and either app will automatically read nil
once it expires in 100 seconds. And both Rails and Sinatra report the class of the data value to be String.
However, if the data is set by the Rails app:
# on Rails:
Rails.cache.write("foo", "from rails", expires_in: 100)
the Rails app read
returns a String (as expected), but Sinatra app 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>
and if the Sinatra app fetches the same key after the expiry, the same data is returned (not nil).
It is certainly possible on the Sinatra app to brute-force it with a new method that get
's the data, and manually handles expiration and data issues using ActiveSupport::Cache::Entry methods, as outlined below.
But it seems like there ought to be some way to have the ActiveSupport::Cache::Entry code handle those details automatically by telling Sinatra to use ActiveSupport::Cache for both setting and getting data?
# 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
Currently the memcache store is configured as per Heroku online documentation:
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
})
EDIT - SOLVED Per accepted answer the key to Sinatra/Rails data interoperability was to explicitly configure the cache store to use ActiveSupport, which still automagically uses the Dalli gem to manage the connection to the memcachier service.
set :cache, ActiveSupport::Cache::MemCacheStore.new(
... # init parameters
)}
which also means using the settings.cache.read/write
methods (vs the settings.cache.get/set
methods used when you configure using Dalli::Client.new).
ADDITIONAL EDIT:
When using the cache inside a model, you cannot access settings.cache directly, need to use Sinatra::Application.settings.cache.read()
Solution
I am not a Sinatra user, Used something like the below in 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")
EDIT
It seems you are using gem dalli, You can also use the DalliStore
instead of MemCacheStore
like the below:
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")
Answered By - user11350468 Answer Checked By - Katrina (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.