-
Notifications
You must be signed in to change notification settings - Fork 143
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
Improved action controller #80
Improved action controller #80
Conversation
The diff sucks, here it is the whole method: def set_locale_from_url
tmp_default_locale = RouteTranslator::Host.locale_from_host(request.host)
if tmp_default_locale
current_default_locale = I18n.default_locale
I18n.default_locale = tmp_default_locale
end
tmp_locale = params[RouteTranslator.locale_param_key] || tmp_default_locale
if tmp_locale
current_locale = I18n.locale
I18n.locale = tmp_locale
end
yield
ensure
I18n.default_locale = current_default_locale if tmp_default_locale
I18n.locale = current_locale if tmp_locale
end |
Of course we can do something like this: def set_locale_from_url
I18n.with_locale(params[RouteTranslator.locale_param_key] || RouteTranslator::Host.locale_from_host(request.host)) do
yield
end
end but I suppose that also setting the default locale will have effects on fallbacks with gems like globalize, but there isn't a proper test |
Thanks man, appreciate the contribution, would you like commit bit in the project? I haven't had time for it lately even though people keep submitting issues now and then. I'll check this deeply lately and probably merge it |
I would like to leave a small note here. I did not test anything and so I may be totally wrong, but isn't any construct like begin
old = Klass.value
Klass.value = new
yield
ensure
Klass.value = old
end prone to race conditions? We had once the case (in a complete different context and not related to this gem) that the Example: 2 requests (r1 and r2) hit the server nearly at the same time. Now for r1 Do you think this might occur here as well? Edit: ok it seems that i18n is not threadsafe by itself ruby-i18n/i18n#269 |
@MarkusHarmsen I'm not sure but I had several issues related to thread and to this gem when it used the before filter without the around block: take a look at #44 Unfortunately I removed that test repositories but I should be able to replicate it I'm really interested in understand if there is a proper way to handle this. Take also a look here: http://guides.rubyonrails.org/i18n.html#setting-and-passing-a-locale |
@MarkusHarmsen reading the i18n source code it seems it is thread safe, at least from my POV looking at this code: https://github.com/svenfuchs/i18n/blob/master/lib/i18n.rb#L22 What you said above is right: begin
old = Klass.value
Klass.value = new
yield
ensure
Klass.value = old
end allows for race conditions to restore the wrong value but in theory: begin
old = Klass.value
Thread[:value] = new
yield
ensure
Thread[:value] = old
end shouldn't. old is local so there's one per thread and value is thread scoped. Anyway, this pr shouldn't have any effect regarding that so I'll merge it and add some more tests regarding thread safety to the gem |
Your totally right! I18n.locale seems to be pseudo globally (per thread), so this is indeed not a problem. Sorry to alarm everybody ;) |
it shouldn't because now it is doing the same thing. I'm wondering if def set_locale_from_url
I18n.with_locale(params[RouteTranslator.locale_param_key] || RouteTranslator::Host.locale_from_host(request.host)) do
yield
end
end is better. I need to do a test with globalize, I will let you know |
Improved action controller
Hi @tagliala
As it already use the |
It is not only about the 2 function calls, it is also about calling functions making the same thing The previous version was something like: def with_host_locale(&block)
host_locale = RouteTranslator::Host.locale_from_host(request.host)
begin
if host_locale
original_default = I18n.default_locale
original_locale = I18n.locale
I18n.default_locale = host_locale
I18n.locale = host_locale
end
def with_locale(tmp_locale = nil)
if tmp_locale
current_locale = self.locale
self.locale = tmp_locale
end
yield
ensure
self.locale = current_locale if tmp_locale
end
ensure
I18n.default_locale = original_default if host_locale
I18n.locale = original_locale if host_locale
end
end I removed the unneeded extra work, it can't hurt
I usually don't think this way... I'm using this gem, I saw an easy way to improve the controller and I submitted a pull request... If there are unoptimized pngs in a gem I use, I also make PRs to fix that even if few bytes are nothing compared to dozens of http requests
Sorry, the above are only specs because I was checking for unintended side effects on my applications. I'm new to profiling, I'm not confident in submitting test results. |
Sorry, I didn't understand your patch this way. Based on your first comment, I tried to find why focus on some method calls and didn't see they did very similar things. Now it's clearer and, even if the performance gain is not obvious (I don't measure it and am not very confident to do it reliably), it can only be better. Thanks for your work and explanations |
Based on how
I18n.with_locale
is implemented (https://github.com/svenfuchs/i18n/blob/master/lib/i18n.rb#L252) I tried to improve the action controller.I aimed to avoid unnecessary function calls to
I18n.with_locale
andself.with_host_locale
, assignments and nested block call. Moreover, the new approach should be faster but I'm very new to profiling so maybe you are interested in writing proper performance testsBeside gem's own tests, I launched some of my applications specs: