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

cache_index missing support to fetch by multiple sets of values #356

Closed
shwetabhgarg opened this issue Sep 28, 2017 · 8 comments
Closed

Comments

@shwetabhgarg
Copy link

Hello,
We're using IdentityCache in our rails model, something like this:

class Product < ApplicationRecord
include IdentityCache
cache_index :ucode
...
end

We're then using this to fetch a list of products, like this:

Product.fetch_by_ucode ['code1', 'code2', ... 'codeN']

However, lately we've been seeing some strange behaviour with the results. Some items are not fetched from cache when keys are provided in a specific order. For example, below is from our production server:

2.4.0 :018 > Catalog::Product.fetch_by_ucode(['I00289', '241890', 'I08491', '083830']).map(&:ucode)
[IdentityCache] (cache_backend) cache hit for IDC:7:attrs:Catalog::Product: id:ucode:16078502576396832033
=> ["083830", "241890", "I00289"]

2.4.0 :019 > Catalog::Product.fetch_by_ucode(['241890', 'I08491', '083830', 'I00289']).map(&:ucode)
[IdentityCache] (cache_backend) cache hit for IDC:7:attrs:Catalog::Product: id:ucode:378519457340401235
=> ["083830", "241890", "I00289", "I08491"]

In both the cases, the keys are same but in different order. This is repeatable, i.e. the result is same when these queries are repeated.

Do the keys need to be in any specific order for this to work correctly?
Any idea on how to fix this? Thanks in advance.

@shwetabhgarg
Copy link
Author

shwetabhgarg commented Sep 28, 2017

Narrowed the cause of issue. The method fetch_by_{field} works correctly for a single value. For an array, it hashes the entire array for searching in backend. A miss does not throw error because the fallback goes to Active Record which interprets input as array and behaves accordingly.
The issue is because this hashed array does not get invalidated when the field is updated, so subsequent fetches for that specific array bring stale data.

A fix for this would be that the method "fetch_by_{field}" should handle the case where the input is a collection. Alternatively, there can be a separate method "fetch_multi_by_{field}".

@dylanahsmith
Copy link
Contributor

cache_index is meant to look for values that exactly match the corresponding columns. On master we now have type casting, which should prevent the fetch_by_ method from kind of working in a way that isn't intended, where the cache would definitely not be updated properly.

Perhaps what you want is a fetch_multi_by_#{field} method. That is planned, but isn't available at the moment.

@shwetabhgarg
Copy link
Author

Thank you for the response. Yes, as I mentioned, "fetch_multi_by_#{field}" suits my case perfectly. If this changes is planned, would you know if there is any expected timeline by when this might be available?

@dylanahsmith
Copy link
Contributor

I don't have a timeline, but it is something that we care about since active record associations couple parts of our codebase that we want to decouple, but we still need a way to load the associated data in a decoupled way using fetch_multi_by_#{foreign_key} where caching is a needed.

@shwetabhgarg
Copy link
Author

@dylanahsmith hello ... were there any updates on this?

@dylanahsmith dylanahsmith changed the title strange behaviour with cache_index cache_index missing support to fetch by multiple sets of values Mar 7, 2018
@dylanahsmith
Copy link
Contributor

Sorry for the delay. I've pushed a cache-index-fetch-multi branch and did some basic testing in a rails console. I still need to add some tests to the test suite for it, but you can try it out in the meantime.

So a query like Product.fetch_multi_by_ucode ['code1', 'code2', ... 'codeN'] would return an array of products similar to Product.where(ucode: ['code1', 'code2', ... 'codeN']).to_a.

A fetch_multi_by_ method is only defined for a cache_index with a single field.

@shwetabhgarg
Copy link
Author

Cool. Thank you for making the changes.
Please let me know when the branch gets merged.

@dylanahsmith
Copy link
Contributor

Fixed by #368

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

2 participants