Ruby-GetText picking random languages (up to 3 on the same page!)

Hi everyone,

We have recently upgraded our project from Rails 2.1.x to Rails 2.3.x,
and in the process also had to upgrade our Ruby-GetText.

Our config/environment.rb now refers to these GetText gems:

config.gem “gettext”
config.gem “gettext_activerecord”, :version => ‘>= 2.1.0’
config.gem “gettext_rails”, :version => ‘>= 2.1.0’

Things seemed to go well as everything now works fine on the
development workstations. But our production server uses a mod_proxy
cluster of Mongrel servers. It seems that now that multiple servers
are involved, Ruby-GetText (or some other component) causes confusion.
When using our language selector and switching languages, the language
is only consistent after the very first request. If you do as much as
reload the page, you may end up with parts of the page in any of the
languages you had previously chosen.

I managed to end up with a page rendering in German, English and
Spanish at the same time. Even within one partial, the language may
change – the first few columns of a table were labeled in German
while the rest was Spanish.

Our language switcher is an almost direct copy of the “default_locale”
method in the Ruby-GetText documentation:

http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html#before%2Fafter_init_gettext

The current code is here, in the define_locale method:

http://code.zhdk.ch/projects/leihs/browser/trunk/app/controllers/application_controller.rb

I’ve placed some logging around those bits of the method that save the
user’s language to the database, and that seems to work fine, the
language is always saved correctly and always retrieved correctly.
Before the set_locale call the GetText.locale.current might be wrong,
but after set_locale it always returns the correct locale. Yet the
page is translated in any wild way to any language.

GetText initialization seems to work, because if I replace that method
with this:

def define_locale
set_locale ‘de_CH’
end

The language is always German (Switzerland) and all the spooky
language flipping stops.

Are we making any massive mistakes in our language setting? It has
worked fine since Rails 1.2.x through 2.0.x when we did our last
upgrade, but perhaps we missed something? Maybe the problem only
appears when using mod_proxy and mongrel_cluster?

Any further information or speculation would be very welcome.

Kind regards,

Ramón

Just a thought, are you fragment caching anything ?

Justin

2010/2/2 Ramón Cahenzli [email protected]:

On Feb 2, 12:07 pm, Justin MacCarthy [email protected] wrote:

Just a thought, are you fragment caching anything ?

We suspsected that too, but then discovered that it’s one of the
other applications where we do fragment caching :slight_smile: So no, this one
is innocent.

But thanks for the suggestion. I am now desperate enough to hack Ruby-
GetText itself to find out what it think is going on. Because if both
Ruby-GetText and Rails agree about the locale they are setting and
the both agree about what language to deliver each page in, then it’s
getting spookier and spookier.

Ramón

And hi again,

I have “fixed” the issue, but I didn’t actually find out what’s
causing the problem. I noticed that when I append ?lang=de_CH to a
URL, the whole page is in the same language, absolutely no matter what
the locale is set to. So now I’m overwriting params[:lang] on every
request, because in our case, we never retrieve the language from the
query string anyhow, so this is okay.

The “fix” is here:

http://code.zhdk.ch/projects/leihs/browser/trunk/app/controllers/application_controller.rb

And here again:

before_init_gettext :define_locale

def define_locale
if params[:locale]
set_locale params[:locale]
params[:lang] = params[:locale] # Bug? Gettext seems not to set
the language properly unless this is set
current_user.update_attributes(:language_id => Language.first
(:conditions => {:locale_name => params[:locale]})) if logged_in?
else
locale = logged_in? ? current_user.language.locale_name :
Language.default_language.locale_name
set_locale locale
params[:lang] = locale # Bug? Gettext seems not to set the
language properly unless this is set
end
end
init_gettext ‘leihs’

I still don’t know if the core issue is with some silliness in our
code or whether it’s somewhere in Ruby-GetText, but I will leave this
ugly code in place for now as we need to deploy tonight. I’d still be
happy about any reports of similar issues, or a better solution :wink:

Ramón

Hi again,

I experimented a bit. I put this ugly thing into the gettext gem’s
gettext.rb to see if set_locale sets the right locale:

def set_locale(lang)
logfile = File.open("/tmp/gettext.log", “a+”)
logfile.puts("set_locale requested for: " + lang.to_s)
logfile.close
Locale.set_app_language_tags(lang)
Locale.default = lang
Locale.current = lang
end

And indeed the locale arrives correctly on each and every request. I
made a new test environment with two Mongrel servers running behind
mod_proxy in round-robin fashion. No one else is using this test
environment, so I can be almost sure that every time I reload the
page, another Mongrel server answers it. Now on every single reload, I
see another constellation of random languages, but it is the same
constellation each time, unless I call define_locale.

For example:

(Mongrel no. 1 is serving)
Left sidebar: English
Top navigation: German
Main content pane: Spanish

–> Reload

(Now Mongrel no. 2 is serving)
Left sidebar: German
Top navigation: English
Main content pane: English

–> Reload

(Mongrel no. 1 is serving again)
Left sidebar: English
Top navigation: German
Main content pane: Spanish

The weird thing is that my log file produces this on EACH one of those
requests:

set_locale requested for: de_CH
set_locale requested for: de_CH
set_locale requested for: de_CH

So set_locale arrives at every request, it is always for the same
language, yet Mongrel serves any part of the content in any language
it likes (?).

And further ideas are very much appreciated. In the meantime I am
trying to set up a server environment with mod_rails to see if Mongrel
and mod_proxy are the problem.

Kind regards,

Ramón