Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caching and Pagination ? #63

Open
danramteke opened this issue Jul 26, 2016 · 8 comments
Open

Caching and Pagination ? #63

danramteke opened this issue Jul 26, 2016 · 8 comments

Comments

@danramteke
Copy link

Hi, I'm having a little trouble getting Rails caching to play nicely with this gem. Here's some psuedo code that matches my code fairly well:

# Shows HTTP paging headers, but loads everything into memory
def user_posts
  cache_key = {
    user_id: current_user.id, 
    latest_post: current_user.posts.maximum(:updated_at)
  }

  posts = Rails.cache.fetch(cache_key) do
     current_user.posts.order('created_at DESC')
  end
  render json: paginate(posts), each_serializer: PostSerializer
end

If I do this, I will get the api_pagination HTTP headers. However, I'm loading all of the current_user's posts into memory, which seems like a bad thing.

If I paginate inside the caching block (like below), then I don't get any api_pagination HTTP headers.

# Doesn't show HTTP paging headers, but doesn't load everything into memory
def user_posts
  cache_key = {
    user_id: current_user.id, 
    latest_post: current_user.posts.maximum(:updated_at), 
    page: params[:page]
  }

  posts = Rails.cache.fetch(cache_key) do
     paginate(current_user.posts.order('created_at DESC'))
  end
  render json: posts, each_serializer: PostSerializer
end

Can someone point me in the right direction? I'm having a hard time googling for API Pagination and Rails caching. Perhaps I'm missing something fairly obvious. I'm using kaminari, if that helps.

Thanks so much!

@davidcelis
Copy link
Owner

@danramteke Is your app open source, by any chance? If not, would you be able to reproduce this in a fresh rails app using kaminari and api-pagination and send me the app's code?

@davideghz
Copy link

davideghz commented Oct 25, 2017

Just had the same problem. paginate overrides Rails' render method.

This override is skipped if the application serves the cached results, so in order to get the correct (full) headers in case the request hits the cache, we have better to paginate what the cache returns instead of paginating inside the cache block.

Something like the following should work:

...
posts = Rails.cache.fetch(cache_key) do
  current_user.posts.order('created_at DESC')
end
paginate json: posts, each_serializer: PostSerializer
...

@jacek213
Copy link

jacek213 commented Oct 5, 2018

@davideghz as the author stated, this way you're going to put all posts into cache, and u might have milions of them, so that's not a good solution.

@alemata
Copy link

alemata commented Feb 11, 2019

Hi!! Did anyone find a solution for this? I am having the same issue...

@davidcelis
Copy link
Owner

Hey all, sorry that there's still an issue with this. I'm still happy to look into this, but I haven't experienced the issue, so having access to the source code of one of these apps that I can run locally would help. Or even just a dummy Rails app that's set up to reproduce the problem.

@alemata
Copy link

alemata commented Feb 12, 2019

Hello @davidcelis! Thanks for the reply... I have created a toy project to test this (https://github.com/alemata/pagination_and_cache)

I know this is not the ideal code to test but it's an idea of the issue

Ideeally we should be able to paginate... store that page result in cache and send the responde with pagination headers...

Sorry if I am being not so clear... please ping me with any question

@alemata
Copy link

alemata commented Feb 17, 2019

@davidcelis were you able to review this?! was the project helpfull?

@alemata
Copy link

alemata commented Feb 18, 2019

Ok I think I make it work...

# call paginate outside cache to add headers
paginated = paginate Property.all
paginated_collection = Rails.cache.fetch(Property.cache_key(properties)) do
  # Store just the collection in cache (`paginate method returns the collection`)
  paginated.to_a
end

paginated_collection

I am not sure if there is a nice way to improve this inside the gem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants