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

WIP: Strip out unchanged keys on object update #263

Closed
wants to merge 1 commit into from

Conversation

dblythy
Copy link
Member

@dblythy dblythy commented Oct 21, 2021

New Pull Request Checklist

Issue Description

Draft PR for ideas / suggestions for improvements around this approach.

If this isn't suitable for this project, I'll be happy to work on this branch for my own usage. I would welcome feedback so I can make sure my fork is as good as it can be 😊

Related issue: #242

Approach

Stores objects in JSON form in memory. When objects are saved, adds unchanged keys to SkipKeys.

TODOs before merging

  • Add tests
  • Add entry to changelog

@parse-github-assistant
Copy link

parse-github-assistant bot commented Oct 21, 2021

Thanks for opening this pull request!

  • 🎉 We are excited about your hands-on contribution!

@cbaker6
Copy link
Contributor

cbaker6 commented Oct 21, 2021

Let me know once you add some test cases and get it to pass the test suite and I can provide a review

//

import Foundation
struct JSONStorage {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should conform to ParseKeyValueStorage so it can be accessed like the other storage mediums when necessary:

public protocol ParseKeyValueStore {

@cbaker6 cbaker6 linked an issue Oct 21, 2021 that may be closed by this pull request
4 tasks
@Vortec4800
Copy link

I've followed along the original issue to see the reasoning for needing this, and frankly, I need some mild "object memory" so my PR works to unset values that are explicitly unset, instead of just trying to unset any nil values. (see #264)

I am a bit fearful about having an in-memory cache to compare against, but it's possible I'm just not understanding everything correctly. Take this example:

You fetch the same object (same object ID) in two different places in the app, we'll call those A and B, and you fetch them at the same time. Then after a few minutes, you change all the values in object A, but object B isn't currently being used so it's not changed. The user goes to the place object B is used and changes one property there but not the others. My understanding is that object B being older would compare itself against the cache, see that all the properties are different even though all the data is technically out of date, and on save overwrites everything instead of only the one changed value which is the original goal. Obviously, this probably isn't the best data structure and could potentially be solved in other ways, but I think it illustrates the potential issue with having a global shared cache. I could also see a lot of less experienced developers (or even some more experienced ones) running into this exact issue.

Would it be better for each Parse object to store a snapshot of its own values at the time of each fetch? Then on save it would only compare changes against its own snapshot, instead of a global cache that may change elsewhere. It seems to me this would be a safer way to achieve the stated goal. Am I missing a requirement or otherwise misunderstanding the goal or the proposed solution?

@cbaker6
Copy link
Contributor

cbaker6 commented Oct 28, 2021

Would it be better for each Parse object to store a snapshot of its own values at the time of each fetch? Then on save it would only compare changes against its own snapshot, instead of a global cache that may change elsewhere. It seems to me this would be a safer way to achieve the stated goal. Am I missing a requirement or otherwise misunderstanding the goal or the proposed solution?

This approach could possibly work, the storage should be part of each object as a property. Centralized cache will attempt to make the SDK work like its using reference types and will cause a ton of issues. The key (name of the property) of the local storage (let's say it's the JSONStorage or a Dictionary) can be added to SkipKeys so it's never encoded to the server. This would work similar to ParseOperation. There maybe even a way to user ParseOperation directly for the storage instead of adding something else as every ParseObject already has a ParseOperation.

let previousStore = store[id],
let json = try JSONSerialization.jsonObject(with: encoded, options: []) as? [String: AnyObject] {
for keyName in json.keys where
(json[keyName] as? NSObject) == (previousStore[keyName] as? NSObject)
Copy link
Contributor

@cbaker6 cbaker6 Nov 4, 2021

Choose a reason for hiding this comment

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

Will need to remove casting to NSObject as it doesn't work well with this SDK. See #275 for workaround, particularly the updated ParseOperation set method. See commit with failing tests and results.

@mtrezza
Copy link
Member

mtrezza commented Sep 3, 2022

Re-opened as this PR suggests improvements tracked in #401; not sure why this has been closed.

@cbaker6
Copy link
Contributor

cbaker6 commented Sep 11, 2022

Closing due to inactivity since 10/21. @dblythy feel free to reopen if you can address the issues mentioned in #263 (comment), #263 (comment), and #263 (comment) and if you think the contribution of this PR will be an improvement over #406

@cbaker6 cbaker6 closed this Sep 11, 2022
@mtrezza
Copy link
Member

mtrezza commented Sep 11, 2022

Since you closed this, we'll need to open another issue #408 to track this discussion about further improvement.

@mtrezza mtrezza mentioned this pull request Sep 11, 2022
3 tasks
@dblythy
Copy link
Member Author

dblythy commented Sep 12, 2022

Yes - sorry - I closed this as hearing the valid comments from @Vortec4800, I decided this approach probably wasn't the best way to go. I might reconsider / retry having a crack again in the future

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