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

improve performance when has data conflicts #84

Merged
merged 2 commits into from Sep 20, 2018

Conversation

elijahdou
Copy link
Contributor

In this pr, i do 2 things. The first one, I adapte the swift4 syntax to eliminate the warnings. The second one is performance improvement. Performance improvement as follow, when called dataHolder.setData(data, changeTime: ChangeTime()) method, if method return directly because of the conflict resolution mechanism,and code logic will continue to write data to the cache. In this case, it is unnecessary.

@plivesey
Copy link
Owner

Sorry for the slow response on this one. I was camping over the weekend. Taking a look now. :D

*/
mutating func setData(_ data: T, changeTime: ChangeTime) {
mutating func setData(_ data: T, changeTime: ChangeTime) -> Bool {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add @discardableResult here so the _ = isn't needed everywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i have finished this work,check it please。

@@ -178,7 +178,7 @@ extension CollectionDataProvider: SharedCollection {
listenForUpdates(model: batchModel)

if !isPaused {
dataHolder.setData(newData, changeTime: ChangeTime())
_ = dataHolder.setData(newData, changeTime: ChangeTime())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these once you've added @discardableResult

@plivesey
Copy link
Owner

This change looks great. Thanks a lot. It'd be awesome if you also wrote a test for the new performance optimization (which verified that the cache is not hit if you make a change which is out of date). But, if you're short on time, don't worry about it.

@codecov
Copy link

codecov bot commented Sep 20, 2018

Codecov Report

Merging #84 into master will decrease coverage by 0.12%.
The diff coverage is 76.47%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #84      +/-   ##
==========================================
- Coverage   93.81%   93.69%   -0.13%     
==========================================
  Files          47       47              
  Lines        4784     4803      +19     
==========================================
+ Hits         4488     4500      +12     
- Misses        296      303       +7
Impacted Files Coverage Δ
RocketData/DataModelManager.swift 100% <ø> (ø) ⬆️
RocketData/Logger.swift 28.57% <ø> (ø) ⬆️
RocketData/BatchDataProviderListener.swift 88.23% <ø> (ø) ⬆️
RocketData/DataHolder.swift 88.88% <66.66%> (+1.38%) ⬆️
RocketData/DataProvider.swift 84.17% <75%> (-0.79%) ⬇️
RocketData/CollectionDataProvider.swift 95.58% <78.26%> (-1.72%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e683826...c4365ea. Read the comment docs.

Copy link
Owner

@plivesey plivesey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks again.

@plivesey plivesey merged commit 2d7cb0d into plivesey:master Sep 20, 2018
@plivesey
Copy link
Owner

I'm going to do the same to the Consistency Manager and then update cocoapods today

@plivesey
Copy link
Owner

Sadly, I can't update the consistency manager because of a cocoapods issue: CocoaPods/CocoaPods#8117 (unless I'm doing something wrong here). Going to wait on that issue to see what happens.

@plivesey
Copy link
Owner

🚀 RocketData (7.0.0) successfully published

Sorry for the delay...ran into several issues with cocoapods and travis. But all fixed now.

@elijahdou
Copy link
Contributor Author

elijahdou commented Oct 23, 2018 via email

@elijahdou elijahdou deleted the performance branch October 23, 2018 15:58
@plivesey
Copy link
Owner

Regarding the first comment, this was a difficult API problem to solve when writing the library. Originally, the library actually behaved how you wanted it to, but it actually caused a lot of complaints in practice. People wanted a block API for updating from the cache. Originally, this just called the delegate method, but this was annoying because you'd lose context. So, we decided to only call the delegate method when the change came from another source. It also makes it very hard to write code like this:

tableView.beginUpdate()
dataProvider.insert(newItem)
tableView.insertRowAtIndex(4)
dataProvider.delete(newItem)
tableView.deleteRowAtIndex(3)
tableView.endUpdates()

If you want, you could easily fix this for your own app by subclassing CollectionDataProvider and adding your own delegate callbacks. So something like:

override func insert(_ newData: [T], at index: Int, shouldCache: Bool = true, context: Any? = nil) {
    super.insert(newData, at: index, shouldCache: shouldCache, context: context)
    delegate.collectionDataProviderHasUpdatedData(self, ...)
}

It's also too much of a breaking change to change the API for all users since most people are relying on the old behavior.

For the second example, paging is a very complex thing to do with a cache. It tends to expire very quickly as rows are added or deleted. For instance, say you save page 1 and page 2 with items 0-9 and 10-19. Then you reload from the network and get a new set of items A-C and 0-6 (because we have 3 new items). Now, loading page 2 is incorrect because it'll return 10-19 and be incorrect!

So, we advise that you cache all pages under one key. So, your network request may be paged, but your cache shouldn't be. Simply keep adding to the same collection provider.

So:

  1. Download page 1 from the network and add it to the collection provider
  2. Download page 2 and add it to the same collection provider
  3. Next time the app loads, when you retrieve from the cache, you'll get BOTH pages
  4. Refresh from the network and merge your data

Does that make sense? Maybe if you gave me some more information on exactly how your server pages data, I can be of more help.

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

Successfully merging this pull request may close these issues.

None yet

2 participants