Обмен глобальными ссылками среди потоков jruby и внутри приложения Rack - PullRequest
2 голосов
/ 09 августа 2010

Я пытаюсь создать счетчик статистики (похожий на страус для scala от Твиттера), но с трудом проверяю, чтобы все мои потоки имели к нему доступ.Мой класс Stats определен так:

class Stats
  @@counters = {}
  .. accessors ..

  def self.incr(counter, amt = 1)
    if !@@counters[counter]  
      @@counters[counter] = java.util.concurrent.atomic.AtomicInteger.new()
    end
    @@counters[counter].getAndAdd(amt)
  end
end

Я знаю, что есть некоторые проблемы с безопасностью потоков самого хэша счетчиков.Если я создаю потоки вручную, кажется, что они могут получить доступ к Stats.counters глобально, но я пытаюсь создать приложение для рэкапа (Sinatra, встроенное в Jetty с помощью jetty-rackup), чтобы показать эту информацию, а в этом приложении SinatraСтатистика пуста.Есть ли хороший способ поделиться этим счетчиком с другими частями приложения или sinatra делает что-то, что очищает область глобальных переменных?

1 Ответ

2 голосов
/ 09 августа 2010

Мы обсуждали это на IRC #jruby, но просто для повторения здесь для потомков, я думаю, что вы столкнулись с ситуацией, когда jetty-rackup создает и объединяет в пул несколько сред выполнения для использования для обслуживания запросов.В каждой из этих сред выполнения загружен один и тот же код Ruby, но они не знают друг о друге, аналогично нескольким процессам Ruby.У вас есть много возможностей для совместного использования состояния между ними.

  • Использование класса Java (с одноэлементным экземпляром или статическими методами / полями)
  • Использование специального кэширования Java в памятибиблиотека
  • Использование сеанса Java Servlet
  • Использование внешнего механизма (memcached, DB и т. д.)
  • Многие другие
...