2016-04-15 2 views
2

Я новичок в целлулоид, но я не понимаю, почему, в моем приложении Rails, мои фьючерсы потерять текущую локаль:Рубин целлулоид «окружающая среда»

puts "locale OUTSIDE #{I18n.locale}" 
data.map do |item| 
    Celluloid::Future.new { puts "locale INSIDE #{I18n.locale}"; serialize_item(item) } 
end.map(&:value) 

в основном я получил что-то вроде

locale OUTSIDE en 
locale INSIDE it 
locale INSIDE it 
locale INSIDE it 
locale INSIDE it 
locale INSIDE itlocale INSIDE it 
locale INSIDE it 

locale INSIDE it 

locale INSIDE it 

и когда я меняю локаль фьючерсы продолжать считать свою локаль по умолчанию: это

Я чувствую, что я что-то не хватает ... основной

+1

К тому же, какую проблему вы решаете с помощью приложения Celluloid в Rails? Вы используете C Ruby или JRuby/Rubinius? – bbozo

+0

Я на самом деле загрязняю свои руки в другом коде .. кто использовал фьючерсы, которые вызывают внешние службы, которые возвращают локализованные данные. Теперь я занимаюсь локальными динамиками. – masciugo

ответ

2

Celluloid фьючерсы получить выполнен в виде отдельного пула потоков (а не другой процесс, так как некоторые ответы предполагают),

I18n.locale значение сохраняется в переменной области видимости отдельной нити http://www.rubydoc.info/docs/rails/2.3.8/I18n%2FConfig%3Alocale:

только значение конфигурации, которое не является глобальным и имеет область действия для потока: locale. По умолчанию используется default_locale.

Значение, которое вы устанавливаете вне рабочих потоков, не применяется в рабочих потоках.

Вам нужно:

  1. использование I18n.default_locale если вы хотите конфиг будет распространяться на все рабочие потоки в процессе, или
  2. отправить локаль в качестве параметра в будущее и установить его (быть обязательно очистите его еще раз, чтобы убедиться в том, что блок или смешные вещи могут произойти с другими артистами целлулоида)
+0

Спасибо @bbozo, мне нужно пойти на второй вариант, так как язык динамический. Однако тот факт, что некоторые переменные привязаны к отдельному потоку, заставляет меня чувствовать себя неуверенно с Целлулоидом ... Есть ли какое-нибудь эмпирическое правило или предложения, за которыми я могу следовать? Может быть, потому, что я не настолько разбираюсь в параллелизме, но, думаю, я бы никогда не разобрался в себе. благодаря! – masciugo

+0

'Celluloid' предоставляет доступ к локаторам потоков, но' Futures' выполняются в потоках 'Group :: Spawner', иначе, чем для экземпляров' Actor'. В этом случае проблема не с 'Celluloid', а' I18n', которая, очевидно, не является потокобезопасной. – digitalextremist

+0

@digitalextremist, я не уверен, что вы имеете в виду, я бы предположил, что в многопоточных веб-серверах вы хотите, чтобы локаль была привязана к потоку, какой она есть. Это может быть неожиданными последствиями при объединении с Celluloid, но я ожидал их, потому что, если 'I18n.locale' работал по-другому, поточные веб-серверы не будут работать с' I18n.locale' – bbozo

0

Если вы хотите использовать локаль, передать его в качестве аргумента в конструктор:

Celluloid::Future.new(locale = I18n.locale) { puts "locale INSIDE #{locale}" } 

Я считаю, что блок будет выполнен в новом процессе, и поэтому локаль информация будет теряться.

+0

спасибо, что родился4new ... но bbozo дал исчерпывающий ответ – masciugo