-
-
Notifications
You must be signed in to change notification settings - Fork 735
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
Save eventually issue #831
Save eventually issue #831
Conversation
- The eventually queue should be cleared at each test execution but Parse.getEventuallyQueue().clear() crashes, that's why line 1585 is commented
* master: Correction to gcm artifact name (parse-community#830)
Awesome ! Thanks! Any chance you had the opportunity to identify what’s deadlocking? |
@flovilmart unfortunately no. Also, to be honest, I'm not sure this test reproduces the exact same issue I have in my app because behavior is a little bit different. So maybe it's not a deadlock. |
@dangtz I'm not an Android expert but likely @rogerhu or @Jawnnypoo may have a better grasp. Seems that the assertion that is failing is this one Is it what you'd expect? |
@flovilmart I expected that it fails on another assertion : this one. |
Doesnt't look it's what's failing on travis, I'll have a look with your code. |
@flovilmart sorry, I misunderstood : yes this test is expected to fail here (ParseUserTest.java:1624). |
Ah good then! Thanks! |
…produce exactly issue parse-community#827
* master: Match up all docs with artifact names (parse-community#836) publish fcm / gcm on their subpath (parse-community#835)
@flovilmart now the test fails at the right line. We can see that:
|
Awesome! That helps a lot! |
Yes, now I'm sure the test is right, I will be able to see why the 2nd save freezes. Will let you know. |
Awesome! If you have any questions, don’t hesitate to ask’ we really appreciate you take the time to dive in! That’s the way to go! |
…SessionIsInvalid()
Codecov Report
@@ Coverage Diff @@
## master #831 +/- ##
============================================
+ Coverage 54.61% 64.39% +9.77%
- Complexity 1709 1906 +197
============================================
Files 123 123
Lines 9785 9796 +11
Branches 1372 1375 +3
============================================
+ Hits 5344 6308 +964
+ Misses 4013 2980 -1033
- Partials 428 508 +80
Continue to review full report at Codecov.
|
It seems like the deadlock is happening inside ParseObject in the waitFor() call? ( Parse-SDK-Android/Parse/src/main/java/com/parse/ParseObject.java Lines 1603 to 1604 in ff3e27b
If I had to guess, it would seem that the task queue never quite runs quite right after sessions are closed (because unhandled exception occurred) |
@rogerhu Yes deadlock occurs there but I can't reproduce it with this test. |
I have not followed the conversation with attention but, as someone who has gone crazy on #646 , this smells like it could be it. Just 2 cents, maybe it might save you some time. That one is an issue with the definition of the default pool thread of bolts. The pool size there depends on the machine processor, so I can see how your tests that run on the PC go well, while the app hangs because your smartphone has less CPU cores. AFAIK |
@natario1 I had a look at #646 conversation a few days ago and I would say that it doesn't seem to be related to this issue. This unit test doesn't reproduce the lock because it misses some code to create the conditions of an app relaunch, and then attempt to save again. This is exactly what to do, on a fresh install, to make the lock occur, whatever the device. You can try it with my test app mentioned in #827 |
I've updated the test and now it reproduces the deadlock responsible for #827 |
Is there a design/spec document describing how the ParseObject.operationSetQueue is expected to work? I found that the problem is the way this queue it's managed after a saveEventually :
|
@dangtz can you shoot away the fix so we can have a look and evaluate from there? |
* Improved test for parse-community#827 : - Generalize to any server error that is different to CONNECTION_FAILED (not only INVALID_SESSION_TOKEN) - Added isDirty() checks - fixed test tearDown
On my side I get regression only at ParseInstallationTest.java:193 and ParseInstallationTest.java:151 but I can see that on Travis there is another regression on ParseCorePluginsTest.java:41 About the ParseInstallation tests : can someone explain why saveAsync is expected to be called twice? |
I believe @dangtz a better question is why is the save called less times now :) |
@flovilmart indeed it is :) |
@flovilmart when is the review planned? Do you need more info? |
@parse-community/android can you guys get a look? |
Just to clarify @dangtz , does this solve the save eventually issue? Or does it create a test that shows how to reproduce it? |
@Jawnnypoo this does both : test and solve. The fix is a modification of the ParseObject. handleSaveResultAsync() method to save the state of the object in LDS when the saveEventually fails. |
@dangtz Can you review some of the comments I made when you get a chance? |
@Jawnnypoo sure! Where can I see them ? |
I believe they are marked in this PR if you go to the |
Sorry I can't see any comment in Files changed tab. |
No, sorry, only code. |
Even if you scroll through it? The comments appear inline, within the files |
@@ -256,7 +260,11 @@ public static void initialize(Configuration configuration) { | |||
// isLocalDataStoreEnabled() to perform additional behavior. | |||
isLocalDatastoreEnabled = configuration.localDataStoreEnabled; | |||
|
|||
ParsePlugins.initialize(configuration.context, configuration); | |||
if (parsePlugins == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dangtz Can you explain what the reasoning is for these changes here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes allow to initialize Parse with a mock ParsePlugins object, for test purpose.
The mock ParsePlugins object is needed to reproduce the issue, and calling Parse.initialize() is also needed to reproduce it. These changes are the solution to have both.
@@ -311,6 +319,8 @@ public Void then(Task<Void> task) throws Exception { | |||
} | |||
|
|||
static void destroy() { | |||
ParseObject.unregisterParseSubclasses(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this causing problems? Curious if this was added to help the tests pass, or if it was related to the bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was not causing the problem, and yes it's to help test teardown here by aggregating deallocations. Note that Parse.destroy() was not used anywhere in the project before my changes.
@@ -322,6 +332,8 @@ static void destroy() { | |||
|
|||
ParseCorePlugins.getInstance().reset(); | |||
ParsePlugins.reset(); | |||
|
|||
setLocalDatastore(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here, is this for the tests, or related to the bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For tests, as Parse.destroy() is only used in tests.
That was my fault, I guess I didn't submit the review 🤔 |
No problem, replied to your comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Jawnnypoo could you share your opinion about this?
@Override | ||
public Task<Void> then(Task<Void> task) throws Exception { | ||
if (task.isFaulted()) { | ||
return Task.forResult(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to not propagate the exception in case fetching the store here fails. If exception was propagated, existing ParseInstallationTests would fail (testMissingRequiredFieldWhenSaveAsync and testObjectNotFoundWhenSaveAsync) because they don't create the right conditions for the fetch to work (a CACHE_MISS exception is then thrown). Maybe we should update those tests instead, by creating the right conditions, and let the exception propagate by using onSuccessTask at line 1451 as on my previous commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I think it is best to update the tests to make them have the right conditions for success/expected failure rather than modifying the library to work with the expectations of the tests. I think we can go ahead and merge this in though, as it fixes the issue at hand, and keep this in mind for potentially another pull request if that is cool with you.
Failing test for issue #827