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
Re-fix #2449 #2477
Re-fix #2449 #2477
Conversation
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.
Thanks for opening this PR. I just want to give a heads up that the tests seem to be failing.
I've fixed the formatting issue in the commit above. Note that I have absolutely no idea what caused the test |
I don’t know. Will see what the latest rounds of tests here give us. Something seems to be wrong with your two latest commits. They give me 404 when trying to look at them. EDIT: All of them do now. Is GitHub down? |
That's weird, the links from this pull request give 404 for me as well. Not sure what happened and how to fix it. The links in https://github.com/nullst/fyne/commits/nullst-patch-1 work fine. Part of that is due to a mismatch between e-mail address I used for github and e-mail address configured with git locally, but it should be fixed now, sorry. If nothing else works, maybe I should just make a new pull request with the same content? |
Thanks for working on this, I agree there is still a problem. p.prefLock.RLock()
shouldIgnoreChange := p.ignoreChange
p.prefLock.RUnlock()
if shouldIgnoreChange { // callback after loading, no need to save
return
} Here you see that we have a problem on load as well - we read the file, it sees the change and can then force a write, we don't want this. What do you think @nullst? |
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.
As described on the conversation, I think that this is not the simplest fix - it works around a mistaken use of the ignoreChange
instead of resolving the root problem.
I have implemented the strategy suggested by @andydotxyz above: since loading the preferences file is conceptually a different operation than just an application updating multiple preferences very quickly, I added a new flag, "loadingInProgress" to the |
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.
Iim not sure about numSuspendedChanges
... This counts how many times we write the file in quick succession.
But after writing the file we should never have to re-read it, that is what ignoreChanges
was about in the first place.
Is there some reason you think we need to read the file shortly after we have finished writing it?
Your comment helped me understand the mechanism better, thank you. Mostly, my original changes were not relevant to loading the preferences file at all, I'm concerned with the situation where the application just updates many different preferences in a row. This is kind of similar to what happens during In general, as I see it now, there are three situations we want to avoid:
Based on this description, I've renamed the "ignoreChanges" variable to "savedRecently" since it better reflects the role. I've also removed the comments, as you suggested. Originally the same variable was used to protect against both (1) and (2), and I think it does not lead to the correct logic. |
Thanks, that is a great summary @nullst. if changes > 0 {
p.InMemoryPreferences.FireChange()
} inside the callback that resets the ignore status, which is called after we save. So my question is - why do we need to ensure that we re-load the file after we have written it out a number of times? |
Sorry, I'm not sure I understand the question.
For approach A a more complicated synchronization pattern would be required than just firing up a goroutine with a timer in UPD: I should perhaps also note that |
Ah, great explanation thanks. Should the callback perhaps call save instead of feeding it back through the FireChanges loop again (I think this is what confused me). |
This makes sense, it's actually easier. Now |
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.
Thanks, much clearer now I think - just a small casing issue in the doc
I think we need @Jacalz to OK the changes too |
Description:
The issue #2449 is still not fixed by the pull request #2450 for me since concurrent writes are not the only problem. There is another problem:
preferences.saveToFile()
sets ignoreChanges totrue
for 100 ms (using resetIgnore()).Suggested solution implemented in this pull request:
numIgnoredChanges int
topreferences
. The access is guarded by the same.prefLock
as.ignoreChanges
.p.prefLock.Lock()
instead ofp.prefLock.RLock()
since we modify the contents).resetIgnore()
to resetp.numIgnoredChanges
as well, and if the number was not zero, callp.InMemoryPreferences.fireChange()
. This is not possible asfireChange()
is not an exported method of theinternal
module, so it was made public.Fixes #2449
Checklist: