Поведение потоков в Синатре и Phusion Passenger - PullRequest
1 голос
/ 21 сентября 2011

У меня есть простое приложение Sinatra, работающее поверх Apache через Phusion Passenger.

Когда приложение запускается, я запускаю поток Ruby, который выполняет тяжелые вычисления раз в минуту, оставляя результат в глобальной переменной (к которой затем обращаются в другом месте).

Переменная обновляется и обновляется один раз в минуту, как и ожидалось при использовании rackup, однако при запуске в Passenger это, похоже, не выполняется.

# Seed the initial license data - on Sinatra starting - and
# set it on a global variable.
$license_data = generate_license_data(360)

# Start up a worker thread that will update the license data
# every 60 seconds. This thread will run until termination
# of the parent thread. Only this thread will modify the values
# of the global variable "license_data".
worker_thread = Thread.new do
  while true
   sleep 60
   t = Time.now
   print "Generating license data ..."
   $license_data = generate_license_data(360)
   print " OK (#{seconds_to_string(Time.now-t)})\n"
  end
end

# Generate the actual HTML snippet we need for the license entry
# by accessing the global variable "license_data".
def generate_license_entry
  # The license block.
  @licensechart = {}
  @licensechart[:values] = $license_data[:values_string]
  # Generate the table entry.
  haml :license
end

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

Ответы [ 2 ]

1 голос
/ 09 июля 2012

В зависимости от того, как настроен пассажир, он может иметь более одного запущенного процесса (так что вы будете дублировать расчетную работу в каждом процессе) или ни одного (так как он может закрыть экземпляры, которые не обслуживали запросы для некоторыхвремя).

Использование другой системы для запуска фоновых задач (например, Resque или delayed_job) будет гораздо более надежным и позволит вам настроить Passenger в соответствии с вашими веб-запросами независимо от требований вашего рабочего потока.

0 голосов
/ 22 сентября 2011

Я не совсем в Passenger, но я думаю, что он порождает несколько процессов для обслуживания ответов и, следовательно, не может быть в состоянии обновить и / или получить доступ к переменной. Сохранение и доступ к данным в базе данных должны по крайней мере решить эту проблему. Для этого сценария я лично выбрал бы Resque с Resque Scheduler , который является библиотекой для создания и обработки (повторяющихся) фоновых заданий, что вы сейчас делаете с потоком.

И снова, заявление Пассажира является весьма умозрительным и может быть ошибочным.

С наилучшими пожеланиями

Tobias

...