Comments on Rails cache returning empty string
Post
Rails cache returning empty string Question
I'm trying to understand the root cause of a bug, HTML meta tag for description is not question specific.
On any individual question page, instead of showing an excerpt of the question and top answer, the description found in the <meta name="description">
tag is the standard default back up description. For example, on Meta Codidact it is:
<meta name="description" content="Codidact Meta on Codidact - open, community-run Q&A knowledge sharing">
This can be seen as follows:
- Go to any specific question page on any Codidact community
- Right click on the page and select "View Page Source"
- The default (instead of question specific) description can be seen around line 7
After experimenting in my local development environment I have established that the intended description (an excerpt of the question wording, followed by an excerpt of the top answer wording if present) is only showing when there is no cache entry for the given key (immediately after posting a question, so it is the first time it has ever been displayed). Refreshing the page changes this to the default description, the same as for any other question that isn't being viewed for the first time (the first time by anyone, not just the current user).
I don't understand how caching works with Rails. The following looks like it is correct usage, from my very limited understanding, but it only gives the intended description the first time (when the inner block is calculated due to the lack of a cache entry) and then never retrieves it from the cache on subsequent visits:
app/views/posts/show.html.erb
lines 2-7:
<% content_for :description do %>
<% Rails.cache.fetch "posts/#{@post.id}/description" do %>
<%= @post.body_plain[0..74].strip %>...
<%= @post.children.any? ? @post.children.first.body_plain[0..74].strip : '' %>
<% end %>
<% end %>
The default is being used instead in the following code:
app/views/layouts/_head.html.erb
lines 4-5:
<% desc = "#{SiteSetting['SiteName']} on Codidact - open, community-run Q&A knowledge sharing" %>
<meta name="description" content="<%= content_for?(:description) ? content_for(:description) : desc %>" />
Does this suggest it is successfully storing the cache key (otherwise it would generate the question specific description from scratch every time and show correctly) but storing a value that isn't the same as what was returned the first time and somehow evaluates as falsy?
If I remove the check and force it to output whatever is in the cache, like this:
<meta name="description" content="<%= content_for(:description) %>" />
Then after the initial question specific description (immediately after posting a new question), on every subsequent page refresh it shows an empty string.
I have switched on caching in my local development environment using:
config/environments/development.rb
line 17:
config.action_controller.perform_caching = true
I've also run rails dev:cache
from the terminal.
Initially I was getting log messages about not being able to connect to Redis:
Cache error: method=delete_entry returning=false exception=Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
Cache error: method=read_entry returning= exception=Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
Cache error: method=write_entry returning=false exception=Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
This turned out to be because I hadn't set Redis to start on boot, so I followed the Redis on Fedora instructions and fixed that:
systemctl enable redis
After this redis-cli ping
successfully returned a PONG
. However, I still see the default description on individual question pages.
In redis-cli I can see a non-empty string, but not the string I'm expecting:
127.0.0.1:6379> type "development://1/posts/23/description"
string
127.0.0.1:6379> get "development://1/posts/23/description"
"\x04\bo: ActiveSupport::Cache::Entry\t:\x0b@valueI\"\x06\n\x06:\x06ET:\r@version0:\x10@created_atf\x060:\x10@expires_in0"
If I manually save a string to a key I can retrieve it intact:
127.0.0.1:6379> set qwerty "long string with spaces.... more words"
OK
127.0.0.1:6379> get qwerty
"long string with spaces.... more words"
At this stage I'm not sure if I have caching set up correctly in development. I have confirmed that on the dev server (a.dev.codidact.org
) the same problem happens (a new question shows the question specific description but all subsequent visits show the default). I confirmed the same in production by checking after I posted this question on Collab:
Immediately after posting:
After refreshing the page:
Does the strange string I see in Redis instead of the question description suggest I have a problem with my local setup, or does it point to the root cause of the problem affecting the dev server and production? Are there further things I can check to try to narrow this down?
2 comment threads