Bug #18453
closedYJIT breaks Rails collection caching
Description
A minimal app that demonstrates this issue is available on GitHub. It has:
- One model,
Post
, with a stringtitle
attribute. - One controller action,
posts#index
, which fetchesPost
s 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
Updated by jhawthorn (John Hawthorn) almost 3 years ago
- Assignee set to jhawthorn (John Hawthorn)
Updated by jhawthorn (John Hawthorn) almost 3 years ago
Tracked this down to cache_fragment_name
(https://github.com/rails/rails/blob/main/actionview/lib/action_view/helpers/cache_helper.rb#L240) getting the wrong args, so probably a bug in kwarg handling.
Updated by jhawthorn (John Hawthorn) almost 3 years ago
Updated by jhawthorn (John Hawthorn) almost 3 years ago
- Status changed from Open to Closed
Applied in changeset git|5414de4b6e4372af832e338f8eb7a9fe8de17c84.
YJIT: Fix SP index with optarg and unordered kwarg
Previously when we were calling a method with an optional argument and
multiple keywords arguments which weren't in the order the receiver
expected we would use the wrong SP index to rearrange them.
Fixes Bug #18453
Updated by jhawthorn (John Hawthorn) almost 3 years ago
- Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN to 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED
Updated by alanwu (Alan Wu) almost 3 years ago
Thank you for such a comprehensive bug report!
Updated by naruse (Yui NARUSE) almost 3 years ago
- Backport changed from 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONTNEED, 3.1: REQUIRED to 2.6: DONTNEED, 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONE
ruby_3_1 2640161df5cf18d08ec86a0c1b913d4ee99e102a merged revision(s) 5414de4b6e4372af832e338f8eb7a9fe8de17c84.