Add a #select_multi method to cache stores #10268

Closed
wants to merge 1 commit into
from

Projects

None yet

5 participants

@dasch
Contributor
dasch commented Apr 19, 2013

Allows selecting a subset of a collection for which the cache returns true values. I extracted it from the following usage:

# In a controller.
@readable_posts = Rails.cache.select_multi(*@posts) do |post|
  # This is very expensive:
  can?(:read, post)
end

I'm not sure if it's too specific, but it's really useful and efficient. It uses read_multi, so it only sends a single get to the cache server.

@dasch dasch Add a #select_multi method to cache stores
Allows selecting a subset of a collection for which the cache returns
true values.
a858268
@carlosantoniodasilva

Isn't it the same as proposed in #10234 with fetch_multi?

@dasch
Contributor
dasch commented Apr 19, 2013

They have two very different uses. fetch_multi is used when you wish to compute a value for each object in a collection, and would like to cache the results:

# This will send a single GET to the cache store, plus a SET for each miss. It
# will return an array of whatever the block returned for that object, making it
# equivalent to Array#map.
rendered_comments = Rails.cache.fetch_multi(*comments) {|comment| render(comment) }

select_multi, on the other hand, is used when you wish to select a subset of some collection of objects for which a block returns true, much like Array#select, but
where the result is cached efficiently:

# Also uses a single GET, plus a SET for each miss, but returns a subset of `users`
# instead of the values of the block.
permitted_users = Rails.cache.select_multi(*users) {|user| can?(:do_expensive_stuff, user }
@dasch
Contributor
dasch commented May 7, 2013

@rafaelfranca this is more of a specialized use case, but I'd like to either get it merged or rejected. I'm using a custom variant of it in a real project in order to avoid paying the performance cost of computing the subset of a list of records that a user is authorized to see, e.g.

readable_articles = select_multi(*articles) do |article|
  # This needs to do all sorts of joins.
  can?(:read, article)
end

Without the select_multi method, the above code would be an N+1.

@rafaelfranca
Member

Not sure if this belongs to Rails. @jeremy thoughts?

@dasch
Contributor
dasch commented Aug 10, 2013

@rafaelfranca @jeremy do you have time to review this?

@JonRowe
Contributor
JonRowe commented Apr 6, 2014

@carlosantoniodasilva @rafaelfranca did you fellows ever make a decision on this? It's quite stale but it should either be reviewed or closed as rejected...

@jeremy
Member
jeremy commented Apr 11, 2014

It's a good fit for your need, but it'd be more clearly done outside of the cache store. I had to read the code to understand its purpose and use.

@jeremy jeremy closed this Apr 11, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment