views:

41

answers:

1

I'm trying to create a Stats counter (similar to the one in ostrich for scala by Twitter) but having a hard time making sure that all my threads have access to this. My Stats class is defined like this:

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

I know there are some issues with the thread-safety of the counters hash itself. If I create threads manually, they seem to be able to access the Stats.counters globally but I'm trying to create a rackup application (Sinatra, embedded in Jetty using jetty-rackup) to show this info, and in that Sinatra application this Stats is empty. Is there a good way to share this counter with other parts of the application or is sinatra doing something that's clearing out the global variable scope?

+1  A: 

We discussed this on IRC #jruby, but just to reiterate here for posterity, my best guess is that you are encountering a situation where jetty-rackup is creating and pooling multiple runtimes to use for servicing requests. Each of these runtimes has the same Ruby code loaded but is unaware of each other, similar to multiple Ruby processes. You have many options for sharing state between them.

  • Use a Java class (with a singleton instance or static methods/fields)
  • Use a purpose-built Java in-memory caching library
  • Use the Java Servlet session
  • Use an external mechanism (memcached, DB, etc.)
  • Many more
Nick Sieger
Thanks Nick for answering it and putting the answer here.
David
java-inline might help here
rogerdpack