Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Comments on Rails cache returning empty string

Post

Rails cache returning empty string Question

+2
−0

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&amp;A knowledge sharing">

This can be seen as follows:

  1. Go to any specific question page on any Codidact community
  2. Right click on the page and select "View Page Source"
  3. 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:

Production developer window showing question specific description immediately after posting

After refreshing the page:

Production developer window showing default description 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?

History
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

2 comment threads

Test comment (1 comment)
Sounds like a bug (2 comments)
Sounds like a bug
ArtOfCode‭ wrote about 1 year ago

Doesn't sound like an issue with your caching setup, sounds like a bug to me. I'm not sure whether the string you're seeing is right or not - it looks vaguely like a Marshal string (Ruby's format for serializing native data), but I'm not sure whether it should be that or just a string.

trichoplax‭ wrote about 1 year ago

The first time the description is generated (before caching) it shows up in the HTML as a string. If it's supposed to be serialised in the cache I'd expect the cache string to be longer (it only seems to have a few characters dedicated to the "value" section which seems an unrealistic compression ratio). I don't know whether that means it's not supposed to be serialised or it's just serialising the wrong thing. Thanks for pointing me in a new direction. I'll see if I can find another place that uses similar caching and see what Redis is storing for that.