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

Attempt to re-save installation if Installation was deleted on the server #579

Merged
merged 3 commits into from
Mar 13, 2017

Conversation

hermanliang
Copy link
Contributor

@rogerhu
Copy link
Contributor

rogerhu commented Mar 11, 2017

Besides this PR matching iOS, do you see this issue for yourself?

@hermanliang
Copy link
Contributor Author

hermanliang commented Mar 12, 2017

@rogerhu
The issue would be happended in the following steps (but doesn't happend on iOS device):

  1. App with the following code
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
// put some parameters here
...
installation.saveInBackground();
  1. Install & launch the app
  2. installation added to server successfully
  3. Delete the added installation on the server
  4. Terminate the app and re-launch again
  5. The installation not re-created to the server

The following is my scenario:
I have two environments for the app. One is Sandbox using Database-A (db-A), the other is Production using Database-B (db-B).
The released app might be with Sandbox (for testing/debugging purpose) or Production settings. Both settings are with the same applicationId, so I can easily replace the settings and keep the app data intact.

  1. The device install the app with Sandbox settings first
  2. Launch the app, the installation data would be added to the db-A
  3. Replace the app with Production settings on the same device
  4. Launch the app, the installation data would be not added to the db-B unless I clear app data from Settings App.

If the device with the above installation scenario, the push notification won't be received in production environment due to no installation data in db-B.
But the above scenario doesn't happened on iOS devices.

@rogerhu
Copy link
Contributor

rogerhu commented Mar 12, 2017

Great thanks for the explaination. Is there a way to add a test for this?

@facebook-github-bot
Copy link

@hermanliang updated the pull request - view changes

@hermanliang
Copy link
Contributor Author

@rogerhu
I added a test. Thanks!


installation.saveAsync(sessionToken, toAwait);

verify(controller, times(1)).getAsync();
Copy link
Contributor

@rogerhu rogerhu Mar 13, 2017

Choose a reason for hiding this comment

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

minor optimization -- this can be verify(controller).getAsync();

http://static.javadoc.io/org.mockito/mockito-core/2.7.16/org/mockito/Mockito.html#verify(T)

verify(mock).someMethod("some arg");
 
Above is equivalent to:
verify(mock, times(1)).someMethod("some arg");
 

Copy link
Contributor Author

Choose a reason for hiding this comment

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

update it by 94da911
Thanks

@@ -2815,6 +2815,15 @@ private void rebuildEstimatedData() {
}
}

/* package */ void markAllFieldDirty() {
synchronized (mutex) {
estimatedData.clear();
Copy link
Contributor

Choose a reason for hiding this comment

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

@natario1 will any changes be necessary for safeKeys() if we merge this in?

Copy link
Contributor

Choose a reason for hiding this comment

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

@rogerhu no, it’s OK as it is now.

@rogerhu
Copy link
Contributor

rogerhu commented Mar 13, 2017

I think code coverage will be higher after you rebase. :)

@rogerhu
Copy link
Contributor

rogerhu commented Mar 13, 2017

rebased / force pushed to your branch

@facebook-github-bot
Copy link

@hermanliang updated the pull request - view changes

@facebook-github-bot
Copy link

@hermanliang updated the pull request - view changes

@rogerhu
Copy link
Contributor

rogerhu commented Mar 13, 2017

Lgtm thanks

@rogerhu
Copy link
Contributor

rogerhu commented Mar 13, 2017

lgtm

@rogerhu rogerhu merged commit 809b829 into parse-community:master Mar 13, 2017
@hermanliang hermanliang deleted the resave-installation branch March 13, 2017 03:54
@natario1
Copy link
Contributor

@hermanliang @rogerhu isn’t your method ParseObject.markAllFieldsDirty doing the same of ParseObject.rebuildEstimatedData (ref)?

I think you could have used that instead.

@hermanliang
Copy link
Contributor Author

@natario1 I think the two methods call is not the same and also for different purposes. ParseObject.rebuildEstimatedData does not force all fields to get dirty because it uses estimatedData.put(key, value) to rebuild estimatedData and it does not change the operations, but performPut(key, value) will update the operations.

@rogerhu
Copy link
Contributor

rogerhu commented Mar 13, 2017

Can we use markallDirty inside the rebuildEstimatedData function? Seems like it's repeated?

Also it should be plural markAllFields

@hermanliang
Copy link
Contributor Author

hermanliang commented Mar 14, 2017

@rogerhu They're different.
rebuildEstimatedData vs. markAllFieldDirty

  1. performPut(key, value) also updates the operations.
  2. rebuildEstimatedData will be called before/after update to the server (ex. handleSaveResultAsync -> setState)

So if use markAllDirty inside the rebuildEstimatedData, the transmission size might be increased.

  1. All fields will be transferred to the server instead of modified (dirty) fields only.
  2. After updating to the server, the data is dirty again.

@rogerhu
Copy link
Contributor

rogerhu commented Mar 14, 2017

Gotcha. They are different.

Looking at https://github.com/ParsePlatform/Parse-SDK-iOS-OSX/blob/2504c19f03698b4f7d89a22708133a410b17fba9/Parse/PFInstallation.m#L73-L80 though markAllFields (should be plural) puts the estimatedData. Yours seems to clear and then write the current state instead of the cached data?

@hermanliang
Copy link
Contributor Author

Yes, the cached installation needs to be rebuilt by new installation after being saved to the server.
To do this, the existing installation needs to be saved as a new installation.

  1. Clear objectID (assign null).
  2. Mark all fields as needed for updates.

After the re-saving process, cached installation file will be overwritten by new one.

The above operation seems to not allow when the local datastore is enabled due to objectID is unchangeable after it's created. (But I think it should be allowed in this case.)

BTW, thanks for your correction. I created a PR (#602) for renaming the function (markAllFieldDirty -> markAllFieldsDirty).

@rogerhu
Copy link
Contributor

rogerhu commented Mar 15, 2017

great thanks for the explanation.

I guess my question is that markAllFieldsDirty() in the iOS SDK (https://github.com/ParsePlatform/Parse-SDK-iOS-OSX/blob/2504c19f03698b4f7d89a22708133a410b17fba9/Parse/PFInstallation.m#L73-L80) seems to mark all the cached data entries as dirty.

it seems like you want to clear the cache, reset it to the original state, and clear object ID.

I guess my question is why there's a difference?

@hermanliang
Copy link
Contributor Author

I know your question now. 😄
Yes, they're different and iOS's markAllFieldsDirty is right.
This line should be removed. No needs to clear the estimatedData before reset it to the original state.
I'll submit another PR to fix it.
Thanks!

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

4 participants