avram icon indicating copy to clipboard operation
avram copied to clipboard

Random preload failures even when the model is preloaded

Open jwoertink opened this issue 3 years ago • 4 comments

I get this every once in a while. I'll load a page, and it'll say that the model must be preloaded with X even though that query calls preload_x. Without changing code, sometimes just refreshing the page fixes it. I've ignored it because it's a really weird intermittent issue, but now @robacarp has also seen this. So there's some weird race condition somewhere happening.

jwoertink avatar Jan 28 '22 23:01 jwoertink

This may be related to cache pollution with preloads:

Here's the scenario

  • say I'm logged in as user id=1.
  • my current_user function will look up user id=1 with every page load.
  • now i visit a page which exists for all users, eg /users/:id, but i visit it for myself
  • the action on that page runs another query, pulling the id from the url, but that query needs additional preloads
  • the query will be run and short circuited by the cache (what we want!)
  • the preloads will also be short circuited by the cache (not what we want :(

So basically the first query runs UserQuery.find(session[:user_id]), then the second one runs UserQuery.new.preload_stuff.id(id).first (technically the same query, but with additional preloads), then you get the preload error because instead of giving you the query you just requested, it actually gave you the query results from current_user.

This could be a potential solution provided by @robacarp

 def results : Array(T)
    records = cache_store.fetch(cache_key, as: Array(T)) do
      exec_query
    end
    preloads.each(&.call(records))
    records
  end

jwoertink avatar Oct 03 '22 20:10 jwoertink

  def results : Array(T)
    cache_store
      .fetch(cache_key, as: Array(T)) { exec_query }
      .tap { |records| preloads.each(&.call(records)) }
  end

This has been working for me this afternoon. Here is a terminal capture which shows both the current behavior and the improved behavior with the code snippet above. Note the text [using CURRENT cache+cached preload algorithm] and [using IMPROVED cache+cached preload algorithm] which indicate what algorithm was being used at the time of the request.

robacarp avatar Oct 03 '22 22:10 robacarp

@jwoertink I noticed this bug too. Is there any progress on this?

notramo avatar May 07 '23 02:05 notramo

Not yet. I've tried looking in to it and haven't been able to make a solid minimal reproduction of the issue.

jwoertink avatar May 07 '23 19:05 jwoertink