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
Wait for goroutines to finish when firing a change to an app preferences #2246
Conversation
Just a minor thought not related to the contents. Can you please name the title of the PR (this and in the future) to what it does and not just what it fixes? It is very hard to glance over numbers and remember what it does. |
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.
Just some small suggestions.
ah sorry for that, the title has been changed |
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 looks good to me. I'll let someone else look on it as well though because I'm away from my computer and can't test it locally.
When running this I get deadlocks at runtime in an app that leans heavily on preferences. You can check out https://github.com/fynelabs/notes, when running (after a few edits) I see:
That was when trying to quit the app, the window disappeared but the process did not exit. Oh, apologies I should have said earlier, thanks for this - I had wondered if something was incorrect as I realised that sometimes this notes app did not save the final character when making notes and exiting! |
waitGroup *sync.WaitGroup to wg *sync.WaitGroup
I have tried your app and i can't replicate the issue, though sometimes the app does not save the whole string (as you said some chars are left) (some saves are not being saved?) can you please provide more info about how to replicate this? |
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 the code looks good now, but I missed that line of documentation isn't particularly clear.
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.
Nice thanks
I will have a look at this again later today. Want to make sure that it works for my use cases before we merge it :) |
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.
Works perfectly fine in my testing. Nice work!
…ces (#2246) Mainly there was two problems: - the first and probably the main bug is that sometimes the app closes too early without waiting for the goroutines that were called in [fireChange()](https://github.com/fyne-io/fyne/blob/3814a66f75ff5d24be6fa107f1dfb9c4faa859b1/internal/preferences.go#L69) and one of those goroutines is the one that calls [save()](https://github.com/fyne-io/fyne/blob/3814a66f75ff5d24be6fa107f1dfb9c4faa859b1/app/preferences.go#L35) an easy fix was to implement the sync.WaitGroup functionality which i expected to work just fine, yet it didn't due to - the second issue which was a misuse of the lockers, in lines [70 and 71](https://github.com/fyne-io/fyne/blob/3814a66f75ff5d24be6fa107f1dfb9c4faa859b1/internal/preferences.go#L70-L71) are using Lock() and after that there are goroutines that are expected to read the same struct, well they won't be able to because Lock() only allows one goroutine (read/write) at a time and in fact the goroutines functions that were thought are being executed were actually not, they were just in stuck position waiting for the fireChange() to return (and to trigger it's defer function to Unlock()) so all those go l() were only waiting for fireChange() to return then get executed, well after the fix (1) the function will never return because it's waiting for the goroutines functions which will never work either because they are waiting for fireChange() ,,, deadlock ; the fix was pretty clear is to use RLock() instead of Lock() that way, where multiple goroutines can read(but not write) the struct and the fireChange() will only returns after all the goroutines are done and only after that the app will close Fixes #2241
Description:
Mainly there was two problems:
Fixes #2241
Checklist: