What is meaning of 0/cache in redis://localhost:6379/0/cache - ruby-on-rails

While adding redis as my cache store in Rails app,
i added the redis url as redis://localhost:6379/0/cache.
What is the meaning of 0/cache in the redis URL?

You may configure redis to use many databases.
The 0 means you are using the first of them (id=0).
The cache is the namespace of the database.
Depending on where you set this url, you are actually telling to use redis caching and values will be saved/retrieved etc from the database 0 and namespace cache.

Related

Rails.cache.clear returns nil

I have this setup
config.cache_store = :redis_store, ENV['REDIS_CACHE_URL']
$ redis-cli
127.0.0.1:6379> set random_key 1
OK
Now I go to the console and do Rails.cache.clear which returns nil
And I am still able to access the key random_key in the redis-cli. It did not clear the cache.
I could not read what Rails.cache returns here too ruby/2.3.4/lib/ruby/gems/2.3.0/gems/railties-4.2.8/lib/rails.rb
Is Rails.cache.clear is supposed to return true?
Can someone please help me out if my understanding is wrong?
redis-cache stores data under a particular namespace.
For example, if you've configured redis-store according to Documentation, then cache keys will be stored under cache namespace. That means, that when you Rails.cache.write("random_key", "key") a key cache:random_key will appear in the Redis. Therefore, when you Rails.cache.clear, only keys under cache namespace will be deleted.
Hence, if you manually create random_key in Redis, Rails.cache.clear won't remove it. But if you manually create cache:random_key, it will.
Be careful when using Rails.cache.clear it will invalidate all the keys for the application (source)
[~Not sure if this is the best place for this answer~]
This helpful article was a great way for me to understand caching when changing versions of Rails from 5.1+ to Rails 6.1+. The article talks about options for generating a cache key with or without versioning.
In the instance of my application, versioning was needed but not turned on when upgraded to Rails 6.1:
#in application.rb
config.active_record.collection_cache_versioning = true
Then within the application code where object.cache_key is called, I had to change it to object.cache_key_with_version (source)

How to get cache expiration date in Rails 3 using the Dalli gem?

I have a Rails 3 application that uses the Dalli gem to manage its cache.
I need to check if a certain part of the application is setting the expiration date of the cache correctly, but can't find a way to manually check that on a specific fragment.
I found this answer, but it doesn't work with Dalli.
Is there another way?
You have a mistake when use read_entry method.
Rails.cache.send(:read_entry,'cache/entry/key',{})
The 'cache/entry/key' should not begin with the namespace.
for example:
The namespace is 'aaa', the key is 'aaa:a_key_name', then the 'cache/entry/key' should be 'a_key_name'.
this script may work: https://gist.github.com/bkimble/1365005

Ruby on rails : memcached read value is nil

I've inherited a Rails project that looks like it's using memcached.
I have a controller, in one method I'm storing a value in the cache with:
Rails.cache.write("key", #var)
in another method subsequently called in the same controller I read it back with:
#var = Rails.cache.read("key")
and the variable is nil. Why is caching not working?
I've just started using ROR so there's a good chance it's something pretty basic.
Just a couple of things to check:
Have you enabled caching in your development environment?
You didn't say which version of RoR you're using, however cache is not enabled by default on development environment.
To enable it, set config.action_controller.perform_caching = true in config/environments/development.rb file.
Have you started memcached server?
If not, start it with memcached -vv
If your memcached server is down when you try to write into cache, the call to Rails.cache.write will return false and the subsequent call to Rails.cache.read will therefore return nil.

Are there Mongo Admin fsync + lock commands available in Mongoid?

If I wanted to call the fsync + lock methods on my database, is there a way to do this with Mongoid in a Rails app? Is there also a way to only specify the replica node that I want to perform this operation on?
I'm trying to create a rake task to perform backups nightly using cron.
Mongoid 2 uses the 10gen supported driver.
Mongoid::Config.master.connection corresponds to the connection object of class Mongo::MongoClient (was Mongo::Connection).
This class has an instance method lock! which does the fsyncLock command, and unlock! is its mate.
http://api.mongodb.org/ruby/current/Mongo/MongoClient.html#lock!-instance_method
http://api.mongodb.org/ruby/current/Mongo/MongoClient.html#unlock!-instance_method
There are no options to these methods to specify member/s of a replica set,
only by socket which is essentially for internal use.
So if you need to fsyncLock a specific replica set member,
I recommend that you connect to it explicitly via an explicit connection,
e.g., Mongo::MongoClient.new(host, port).
client = Mongo::MongoClient.new(host, port)
client.lock!
# ...
client.unlock!
client.close
Mongoid 3 uses Moped and not the 10gen driver.
But you can still use the 10gen driver independently for your rake tasks even if you move to Mongoid 3.
I'm interested in your results and any followup questions.

One Redis server per Rails app?

I've a bunch of rails app on my server that should be able to use Redis as cache engine.
Do I've to start one instance of Redis for each of my application, or does the Redis support scoping?
I'm worried that if I remove one value in one app, the value with the same key will be removed for all of my apps.
I do NOT for example want this to happen.
App 1
Rails.cache.write("key", "value")
App 2
Rails.cache.read("key") => "value"
App 3
Rails.cache.delete("key")
App 1
Rails.cache.read("key") => nil
I suggest running a server for every application. Every additional Redis instance only uses 1 megabyte more memory when empty, so the overhead is small and it is ok to run tens of servers in a single instance. Also an idle Redis server is going to use a minimal amount of memory.
So basically by running multiple servers you are not wasting resources, but instead gaining speed as you'll use all your CPUs or CPU cores, given that Redis is single threaded.
A common method for this is one of two things:
Prefix your keys with some sort of "type" identifier, like app1:key, app2:key.
Use separate DBs for each using SELECT. By default, connections start out against DB 0. If you do SELECT 1 for app1, SELECT 2 for app2, etc., you are guaranteed that no other application will clobber that data.
The solution was to use redis-store with the namespace param.
Here is my config/production.rb file.
# App 1
config.cache_store = :redis_store, {path: "/tmp/redis.sock", db:1, namespace: "app1"}
# App 2
config.cache_store = :redis_store, {path: "/tmp/redis.sock", db:2, namespace: "app2"}

Resources