enriclluelles/route_translator

Issues with rails admin (Thread related)

tagliala opened this issue · 7 comments

Hi @enriclluelles,

we are using this gem together with rails_admin and we are experiencing a serious issue in production environment.

It seems that the locale "leaks" from the website request to rails admin.

We can provide an example:
Access to the admin area here: http://polar-plains-1091.herokuapp.com/admin

User: demo@example.com
Pass: demo

You will see the rails admin interface in English

Then open http://polar-plains-1091.herokuapp.com/it and try to refresh both pages at the same time: rails admin will randomly show up in Italian

We are using puma and unicorn

The source code of this application is here: https://github.com/diowa/route_translator_rails_admin_issue

Any help would be appreciated

Extra information:

  • It also happens on rails 3.2.15
  • It also happens with Thin webserver

Hi there, thanks for the detailed issue. I will take a look soon.

Thanks. Unfortunately I'm not able to help in this, I just suppose there is some kind of concurrencing issue involved. We tried to use an around filter here: https://github.com/diowa/route_translator/tree/around-filter but we didn't try it in production because this is causing issues in the localized path helpers (root_locale_path) even if all tests pass

I suppose the problem is this one: http://stackoverflow.com/a/13931928/1675923

I deployed on heroku a new version with the around filter https://github.com/diowa/route_translator/blob/around-filter/lib/route_translator/extensions/action_controller.rb#L5 and I'm not able to reproduce the bug at the moment.

Specs pass, but I'm far to submit a pull request because I don't understand what I'm doing. Any help would be very appreciated :)

# Running tests:

.....................................

Finished tests in 0.275900s, 134.1066 tests/s, 938.7459 assertions/s.

37 tests, 259 assertions, 0 failures, 0 errors, 0 skips

ruby 1.9.3p545 (2014-02-24 revision 45159) [x86_64-darwin13.1.0]

# Running tests:

Finished tests in 0.367576s, 100.6595 tests/s, 704.6162 assertions/s.                                               
37 tests, 259 assertions, 0 failures, 0 errors, 0 skips

ruby -v: ruby 2.0.0p451 (2014-02-24 revision 45167) [x86_64-darwin13.1.0]

# Running tests:

Finished tests in 0.272821s, 135.6201 tests/s, 949.3404 assertions/s.                                               
37 tests, 259 assertions, 0 failures, 0 errors, 0 skips

ruby -v: ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]

this is causing issues in the localized path helpers (root_locale_path) even if all tests pass

That was because the around filter didn't affect locale in specs. So I fixed the specs and now i get the proper results

E.g: with before_filter

> I18n.default_locale
=> :it
> # visit_some_english_route
> I18n.locale
=> :en

With around_filter

> I18n.default_locale
=> :it
> # visit_some_english_route
> I18n.locale
=> :it

http://polar-plains-1091.herokuapp.com/ uses around filter
http://glacial-waters-6054.herokuapp.com/ uses before filter

Code: https://github.com/diowa/route_translator_rails_admin_issue
(the only difference is the around vs before filter)

Both rails admin routes skips the filter

  skip_around_filter :set_locale_from_url, if: -> { self.class.parent == RailsAdmin }
  skip_before_filter :set_locale_from_url, if: -> { self.class.parent == RailsAdmin }

I came up with this test... maybe not the best test ever

require 'rest_client'
require 'pp'

def http_request(url, current_locale)
  response = RestClient.get(url)
  {
    url: url,
    passed: !!(response =~ /Current locale:\n<b>#{current_locale}<\/b>/)
  }
end

around_filter = {
  'http://polar-plains-1091.herokuapp.com/it' => {
    test: 'it',
    failed: 0,
    passed: 0
  },
  'http://polar-plains-1091.herokuapp.com/admin' => {
    test: 'en',
    failed: 0,
    passed: 0
  }
}

before_filter = {
  'http://glacial-waters-6054.herokuapp.com/it' => {
    test: 'it',
    failed: 0,
    passed: 0
  },
  'http://glacial-waters-6054.herokuapp.com/admin' => {
    test: 'en',
    failed: 0,
    passed: 0
  }
}

[around_filter, before_filter].shuffle.each do |results|
  threads = []
  50.times do
    results.each do |k, v|
      threads << Thread.new { Thread.current[:output] = http_request(k, v[:test]) }
    end
  end

  threads.each do |t|
    t.join
    if t[:output][:passed]
      results[t[:output][:url]][:passed] += 1
    else
      results[t[:output][:url]][:failed] += 1
    end
  end
  pp results
end

Results:

{"http://glacial-waters-6054.herokuapp.com/it"=>
  {:test=>"it", :failed=>0, :passed=>50},
 "http://glacial-waters-6054.herokuapp.com/admin"=>
  {:test=>"en", :failed=>39, :passed=>11}}
{"http://polar-plains-1091.herokuapp.com/it"=>
  {:test=>"it", :failed=>0, :passed=>50},
 "http://polar-plains-1091.herokuapp.com/admin"=>
  {:test=>"en", :failed=>0, :passed=>50}}

The impact of this bug is huge when dealing with rails admin and globalize, because Rails Admin will save invalid records (validation passes, but the record is not valid because it won't store translated fields in the proper locale)

What do you think?