Project

General

Profile

Actions

Bug #18453

closed

YJIT breaks Rails collection caching

Added by georgeclaghorn (George Claghorn) 6 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) +YJIT [x86_64-linux]
[ruby-core:106923]

Description

A minimal app that demonstrates this issue is available on GitHub. It has:

  • One model, Post, with a string title attribute.
  • One controller action, posts#index, which fetches Posts in reverse order of creation into @posts.
  • A root route to posts#index.
  • One view, app/views/posts/index.html.erb, which uses Rails collection rendering and caching as follows:
<ul>
  <li><%= render partial: "posts/post", collection: @posts, cached: true %></li>
</ul>
  • A partial, app/views/posts/_post.html.erb as follows:
<% cache post do %>
  <li><%= post.title %></li>
<% end %>

I deployed this app to Heroku here. I configured it to use a Redis cache store.

I added 100 posts like so:

$ heroku run rails c
> 100.times do |i|
*    Post.create! title: "Post ##{i + 1}"
* end

All requests to the app index, /, show the posts in reverse chronological order as expected, with cold and warm cache:

* Post #100 
* Post #99
* Post #98
* Post #97
* Post #96
* Post #95
...

I enabled YJIT by setting the RUBYOPT environment variable to --yjit --yjit-exec-mem-size=32 and restarted the app server. I cleared the Redis cache with heroku run rails r 'Rails.cache.redis.flushall.

The first request to / with cold cache begins repeating Post #1 after #92:

* Post #100
* Post #99
* Post #98
* Post #97
* Post #96
* Post #95
* Post #94
* Post #93
* Post #92
* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
...

All subsequent requests repeat Post #1 100 times:

* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
* Post #1
...

On restart, Post #1 is repeated after #92 for the first request (as in the second-to-last example). Post #1 is repeated 100 times for subsequent requests (as in the last example).

Disabling YJIT and flushing the Redis cache restores the correct behavior.

Rails version: GitHub rails/rails, 7-0-stable branch, revision 499f12f6c03a4114eb649310e65200fe5d894db0

Actions

Also available in: Atom PDF