RocketData icon indicating copy to clipboard operation
RocketData copied to clipboard

One-to-many relationship: retrieve child object from cache

Open agordeev opened this issue 7 years ago • 3 comments

First of all, thanks for the library.

I have two models, both conform to Model protocol:

public struct Person {
    public let id: String
    public let name: String
}

public struct Group {
    public let id: String
    public let persons: [Person]
}

I'm putting a group into the cache:

let person1 = Person(id: "1", name: "jj")
let person2 = Person(id: "2", name: "name")
let group = Group(id: "1", persons: [person1, person2])
let groupDataProvider = ModelDataProvider<Group>()
groupDataProvider.setData(group)

and then trying to take a person out of there:

let dataProvider = ModelDataProvider<Person>()
dataProvider.fetchDataFromCache(withCacheKey: person1.modelIdentifier) { (model, error) in
    if let error = error {
        print("error \(error)")
    } else {
        print("model \(model) \(type(of: model))")
    }
}

However, nil is returned. Looks like we're unable to get child objects out of cache?

agordeev avatar Apr 09 '17 11:04 agordeev

Sorry for the slow response, but a few things to check:

  1. Put a break point in your cache delegate in: func modelForKey<T: SimpleModel>(_ cacheKey: String?, context: Any?, completion: @escaping (T?, NSError?)->()) At this point, it's up to you to retrieve this object from the cache and so you can debug why this is failing.

  2. This may be because your only caching top level objects. Check out the Cache portion of https://realm.io/news/slug-peter-livesey-managing-consistency-immutable-models/ (20:10). It sounds like you want cache consistency which isn't free with this library. If you want to cache group and person separately, you need to do that work. However, this is work which is pretty easy to write generically (esp since you already have a map/forEach function). At LinkedIn, our models were backed with JSON, and I wrote a module which iterated over the data recursively and cached individual models separately. Then, we recombined them.

plivesey avatar Apr 18 '17 22:04 plivesey

Thanks for your reply, Peter.

This may be because your only caching top level objects.

Yes, that's how I do.

It sounds like you want cache consistency which isn't free with this library. If you want to cache group and person separately, you need to do that work. However, this is work which is pretty easy to write generically (esp since you already have a map/forEach function). At LinkedIn, our models were backed with JSON, and I wrote a module which iterated over the data recursively and cached individual models separately. Then, we recombined them.

Any details how do you deal with that? I'm concerning about cache consistency: let's say I iterate over my Group's descendants and put them into the cache too. Then, I take person1 out of the cache directly, update it and put back into the cache. Will this also update my group, as person1 is its descendant? If not, how to deal with that?

agordeev avatar Apr 19 '17 13:04 agordeev

a blog post on this would be great, I also think it needs to be called out in the documentation. Now I know it it's obvious, but it took me a while to work out cache consistency was the issue.

katalisha avatar Jun 04 '17 23:06 katalisha