-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Allow dev i18n to be more concurrent #20159
Conversation
The recent changes to add live-reloading to the i18n translation files added a few races. This PR fixes these, adds some more comments to the code and slightly restructures a few functions. Signed-off-by: Andrew Thornton <art27@cantab.net>
Where is the race? In old code, the reloadMu locks the store and all locales.
Then, no other access to the maps. For |
Sorry I stand corrected there isn't a race because the previous code was locking the entire translation system for every single translation! This PR suggests using a RWMutexes to allow for much more concurrent behaviour. |
Understand. My opinion is about Return on Investment (ROI). When I was designing the module, IMO in development mode, there is no need for concurrent behavior. So I chose the simple approach. The less code, the fewer mistakes, and the less maintenance work in the future. |
Do you have strong preference to introduce these new mutexes? Personally I still like a simple approach (and there is always a chance to optimize the code if there is really some performance problems), while new mutexes also work and if people like it, either is fine. If no need to add more mutexes at the moment, then the Update: the |
Signed-off-by: Andrew Thornton <art27@cantab.net>
We need the i18n code to be concurrent because without it it will hide concurrency issues elsewhere. |
I've already done all of the work to properly include the double mutex layer.
Your proposed PR involves recalculating the idx for the trKey thus involves relocking the main localestore. Just accept this PR instead of making more PRs. |
If it's the case, I think there could be still a simple patch
|
Could a shared RWMutex work? If yes, then I think the simple approach doesn't have the
Yup, but they are protected by the mutex. Now using a RWMutex,
Sorry for noises, but I think it's clear to describe how one mutex works with a separate PR ..... |
After some refactoring, finally I implemented a 100% write-lock-free live-reloading (if locale file is not changed), by using atomic.Value. If we need to make a 100% lock-free live-reloading, it may be also feasible by using more atomic.Values, the question is whether it is worth. 🤔 |
Honestly. What is wrong with this PR? I don't understand you. I've spent more time arguing with you about this than I actually spent writing the PR. Your proposed "simple" solution will involve locking every translation every second whilst the filestat is checked. In fact instead of using filestats we should be using fsnotify but honestly you've put me off even looking any further at this. Next you start suggesting atomic values? Have you looked at how RWMutex.RLock() is implemented: func (rw *RWMutex) RLock() {
if race.Enabled {
_ = rw.w.state
race.Disable()
}
if atomic.AddInt32(&rw.readerCount, 1) < 0 {
// A writer is pending, wait for it.
runtime_SemacquireMutex(&rw.readerSem, false, 0)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
}
} it's already using an atomic. |
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.
Since we are resuming our lock states right before returning, I think this should simplify it, unless I missed something
Co-authored-by: John Olheiser <john+github@jolheiser.com>
This comment was marked as off-topic.
This comment was marked as off-topic.
The first argument in this PR is about Since there is no data-race, the second is about However, this PR's concurrency is still affected by the locale's So I tried to investigated on it and tried a 100% write-lock-free solution, isn't is better for your proposed better concurrency?
The updated "simple" solution only require read-lock if the locale file is not changed. The original PR about fsnotify has some flaws: it's too complex and many code are copied twice (personally I do not like duplicate code and always try to to avoid them .....), result in no benefit for production, it will require more maintain work in future if the locale module should be refactored. And it's not obvious that it should be closed, Gitea already has some resource leaks, if no necessary I think the Update: if you think the fsnotify is a must and brings real benefit, it could still be used in current code base, without splitting code into duplicate functions: using a goroutine to do write-lock and reload, keeping most other code as before.
OK, I am going to be impolite .... (sorry for I am not a native speaker, so I might misunderstand or mis-express something, you can assume that I have no malice for anyone, just express my feeling): I have been put off many times, especially for some frontend refactorings and some recent PRs, even no feedback at all, I have complained that in discord before.
I have read it before. Why |
The recovery, API, Web and package frameworks all create their own HTML Renderers. This increases the memory requirements of Gitea unnecessarily with duplicate templates being kept in memory. Further the reloading framework in dev mode for these involves locking and recompiling all of the templates on each load. This will potentially hide concurrency issues and it is inefficient. This PR stores the templates renderer in the context and stores this context in the NormalRoutes, it then creates a fsnotify.Watcher framework to watch files. The watching framework is then extended to the mailer templates which were previously not being reloaded in dev. Then the locales are simplified to a similar structure. Fix go-gitea#20210, go-gitea#20211, go-gitea#20217 Replace go-gitea#20159 Signed-off-by: Andrew Thornton <art27@cantab.net>
. |
* upstream/main: Modify milestone search keywords to be case insensitive (go-gitea#20266) Fix toolip on mobile notification bell (go-gitea#20270) Allow RSA 2047 bit keys (go-gitea#20272) Refix notification bell placement (go-gitea#20251) Bump mermaid from 9.1.1 to 9.1.2 (go-gitea#20256) EscapeFilter the group dn membership (go-gitea#20200) Only show Followers that current user can access (go-gitea#20220) Init popup for new code comment (go-gitea#20234) Bypass Firefox (iOS) bug (go-gitea#20244) Adjust max-widths for the repository file table (go-gitea#20243) Display full name (go-gitea#20171) Adjust class for mobile has the problem of double small bells (go-gitea#20236) Adjust template for go-gitea#20069 smallbell (go-gitea#20108) Add integration tests for the Gitea migration form (go-gitea#20121) Allow dev i18n to be more concurrent (go-gitea#20159) Allow enable LDAP source and disable user sync via CLI (go-gitea#20206)
The recent changes to add live-reloading to the i18n translation files made the i18n code totally non-concurrent when using dev. This will make discovering other concurrency related issues far more difficult. This PR fixes these, adds some more comments to the code and slightly restructures a few functions. Signed-off-by: Andrew Thornton <art27@cantab.net>
The recent changes to add live-reloading to the i18n translation files made the i18n code totally non-concurrent when using dev. This will make discovering other concurrency related issues far more difficult. This PR fixes these, adds some more comments to the code and slightly restructures a few functions. Signed-off-by: Andrew Thornton <art27@cantab.net>
The recent changes to add live-reloading to the i18n translation files made the i18n code totally non-concurrent when using dev. This will make discovering other concurrency related issues far more difficult. This PR fixes these, adds some more comments to the code and slightly restructures a few functions.
Signed-off-by: Andrew Thornton art27@cantab.net