Потоки в Rails - params [] сохраняются? - PullRequest
3 голосов
/ 08 октября 2010

Я пытаюсь создать поток в Rails. Мне обычно неудобно использовать потоки, так как мне нужно иметь глубокие знания о цикле запросов / ответов Rails, но я не могу избежать его использования в качестве тайм-аута моего запроса.

Чтобы избежать тайм-аута, я использую поток в запросе. Мой вопрос здесь прост. Поток, который я использовал, обращается к переменной params [] внутри него. И, кажется, все работает хорошо сейчас. Я хочу знать, правильно ли это? Я был бы рад, если бы кто-то смог пролить свет на использование Threads в Rails во время цикла запрос / ответ.

[Начиная награду]

Ответы [ 2 ]

5 голосов
/ 21 октября 2010

Краткий ответ - да, но только до некоторой степени; привязка, в которой был создан поток, будет сохраняться. Параметры будут существовать только в том случае, если никто (включая Rails) изо всех сил не сможет изменить или удалить хэш параметров. Вместо этого они используют сборщик мусора для очистки этих объектов. Поскольку поток имеет доступ к текущему контексту (называемому «связыванием» в Ruby), когда он был создан, все переменные, которые могут быть достигнуты из этой области (фактически, всего состояния, когда поток был создан), не могут быть удалены мусором коллектор. Однако, поскольку выполнение продолжается в основном потоке, значения переменных в этом контексте могут быть изменены основным потоком или даже созданным вами потоком, если он может получить к нему доступ. В этом преимущество - и недостаток - потоков: они разделяют память со всем остальным.

Вы можете эмулировать среду, очень похожую на Rails, чтобы протестировать вашу проблему, используя такую ​​функцию: http://gist.github.com/637719. Как видите, код по-прежнему печатает 5.

Однако это не правильный способ сделать это. Лучший способ передать данные в поток - это передать их в Thread.new, например:

# always dup objects when passing into a thread, else you really
# haven't done yourself any good-it would still be the same memory
Thread.new(params.dup) do |params|
  puts params[:foo]
end

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

Итак, как вы можете видеть, есть веские причины, по которым это не рекомендуется. Многопоточное программирование является сложным , даже в Ruby, и , особенно , когда вы имеете дело с таким количеством библиотек и зависимостей, которые используются в Rails. Фактически, Ruby, кажется, делает это обманчиво легким, но это в основном ловушка. Ошибки, с которыми вы столкнетесь, очень тонки; они будут происходить «случайно» и их будет очень сложно отлаживать. Вот почему такие вещи, как Resque, Delayed Job и другие библиотеки фоновой обработки, используются так широко и рекомендуются для приложений Rails, и я бы порекомендовал то же самое.

1 голос
/ 08 октября 2010

Вопрос в том, поддерживает ли rails запрос в открытом состоянии во время работы потока, чем сохраняет значение.

Значение не сохранится, как только запрос закончится, и я также не рекомендовал бы держать запрос открытым, если в этом нет реальной необходимости. Как говорили другие пользователи, некоторые вещи просто лучше в отложенной работе.

Сказав, что мы использовали многопоточность для одновременного запроса к нескольким источникам и фактически сократили время отклика приложения (это было только для администраторов, поэтому не требовалось быстрое время отклика), и если память правильно работает, Поток может оставить запрос открытым, если вы в конце вызовите метод join и дождитесь завершения каждого потока, прежде чем продолжить.

...