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

RealmResults is not synced in global listener #2926

Merged
merged 3 commits into from
Jun 3, 2016
Merged

Conversation

beeender
Copy link
Contributor

@beeender beeender commented Jun 2, 2016

Close #2408

RealmResults are synced when calling its listener, since we need to
check the table version before calling the listener. So sync it just
after advance read won't be an option - in that way, the result's
listener won't be triggered.

So we notify the global listeners as the last thing to do, at that
point, result will be synced already.

Also a test case is added to ensure the calling sequence of synced
listeners.

@@ -268,6 +267,12 @@ void notifyAllListeners() {
if (!realm.isClosed() && threadContainsAsyncEmptyRealmObject()) {
updateAsyncEmptyRealmObject();
}
// It is very important to notify the global listeners at last.
Copy link

Choose a reason for hiding this comment

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

at

@cmelchior cmelchior changed the title RealResults is not synced in globla listener RealResults is not synced in global listener Jun 2, 2016
AllTypes allTypes = realm.where(AllTypes.class).findFirst();
assertNotNull(allTypes);
allTypes.deleteFromRealm();
final RealmResults<AllTypes> results = realm.where(AllTypes.class).findAll();
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps just realm.where(AllTypes.class).count() instead?

Close #2408

RealmResults are synced when calling its listener, since we need to
check the table version before calling the listener. So sync it just
after advance read won't be an option - in that way, the result's
listener won't be triggered.

So we notify the global listeners as the last thing to do, at that
point, result will be synced already.

Also a test case is added to ensure the calling sequence of synced
listeners.
@Test
@RunTestInLooperThread
public void realmListener_realmResultShouldBeSynced() {
final AtomicBoolean changedOnce = new AtomicBoolean(false);
Copy link
Contributor

@cmelchior cmelchior Jun 2, 2016

Choose a reason for hiding this comment

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

Since you are actually using multiple states. It would probably read more easily if you used an AtomicInteger instead and did switches on the number

@cmelchior cmelchior changed the title RealResults is not synced in global listener RealmResults is not synced in global listener Jun 2, 2016
@@ -268,6 +267,12 @@ void notifyAllListeners() {
if (!realm.isClosed() && threadContainsAsyncEmptyRealmObject()) {
updateAsyncEmptyRealmObject();
}
// It is very important to notify the global listeners last.
// We don't sync RealmResults in realmChanged, instead, they are synced in notifySyncRealmResultsCallbacks.
// This is because of we need to compare the table view version to decide if it changes. Thus, we cannot sync
Copy link
Contributor

Choose a reason for hiding this comment

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

This is because we need to compare the TableView version in order to decide if it changed.

@cmelchior
Copy link
Contributor

Good catch 💯 . Only had minor comments 👍
I am slightly concerned about changing the order of callbacks though. I can see why there is no way around it, I am just concerned if we might break other apps in the process that accidentally relied on that order. On the other hand, we have never promised which order they where called in, and the most important thing is that they are consistent (which they will be after this). Thoughts?

@beeender
Copy link
Contributor Author

beeender commented Jun 2, 2016

I think we should not promise the order of they get called ever... User's code logic should never rely on it. Even we might have a consistent order from now on, but that could be changed in the future.

We can doc something like the orders of calling those listeners are not guaranteed. So, please don't rely on it? or just don't doc it which user should know it is a "undocumented" behaviour.

@cmelchior
Copy link
Contributor

I would probably be fine with just calling it out in the changelog, because as you say. We never promised any ordering.

realm.addChangeListener(new RealmChangeListener<Realm>() {
@Override
public void onChange(Realm element) {
switch (changeCounter.getAndAdd(1)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

minor: similar to getAndIncrement

@nhachicha
Copy link
Collaborator

👍 minor things

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants