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

Fix a bug where simultaneously listening to a reused Preference would not propagate changes to other listeners #1

Merged
merged 1 commit into from May 25, 2019

Conversation

roughike
Copy link
Owner

@roughike roughike commented May 25, 2019

As it turns out, the "initial stable release" was not bug-free.

The bug

If you did this:

final counter = preferences.getInt('counter');

int value1;
int value2;
int value3;

counter.listen((value) => value1 = value);
counter.listen((value) => value2 = value);
counter.listen((value) => value3 = value);

counter.setValue(9);

Only value1 would now contain 9 as expected, while value2 and value3 would be 0.

However, if you did:

int value1;
int value2;
int value3;

preferences.getInt('counter').listen((value) => value1 = value);
preferences.getInt('counter').listen((value) => value2 = value);
preferences.getInt('counter').listen((value) => value3 = value);

counter.setValue(9);

Everything was fine. The bug only appeared when reusing a Preference and when all the listeners were listening to it at the same time.

To show the thing in action, see this screencast sharing a Preference between multiple PreferenceBuilders in a same screen:

ezgif-1-63dfae1b07da

The reason

This bug was introduced by this commit. It happened because the cached T lastValue field should've existed in the onListen() callback, not as a field in the EmitValueChanges transformer.

The purpose was to optimize the Preference stream so that the last emitted value wouldn't be unnecessarily added to the Stream again. Unfortunately, this "optimization" was too effective: it only allowed the first listener to receive the change but the other ones would always miss it.

The fix

The solution was to move the cached value inside the onListen() callback. This way each individual listener would enjoy the caching benefits while actually being able to receive updates.

ezgif-1-7da864d4824e

There is now a test case in place to prevent this from happening again.

@roughike roughike added the bug Something isn't working label May 25, 2019
@roughike roughike merged commit 610d919 into master May 25, 2019
@roughike roughike deleted the bugfix-first-listener-privileges branch May 25, 2019 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant