JRuby
Concurrency
Nick Sieger
EMRubyConf @ RailsConf 2011
Mental
Model




         http://www.flickr.com/photos/solar_decathlon/4524503892/
http://twitter.com/RoflscaleTips/status/61135427813384192
Uncertainty
/* ruby/struct.c */
static VALUE rb_struct_equal(VALUE s, VALUE s2) {
    /* ... */

    if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
        rb_bug("inconsistent struct"); /* should never happen */
    }

    /* ... */
}




                                    O RLY?!
How could this code fail?
class ExpensiveToCreate
  def self.instance
    @instance ||= ExpensiveToCreate.new
  end
end
How could this code fail?
class ExpensiveToCreate
  def self.instance
    unless defined?(@instance)
      @instance = ExpensiveToCreate.new
    end
  end
end
How could this code fail?
     class ExpensiveToCreate
       def self.instance
T2       unless defined?(@instance)
           @instance = ExpensiveToCreate.allocate
T1         @instance.initialize # big pause here
           @instance
         end
       end
     end
Avoid shared mutable state,
     lazy initialization

              MutableConstant.merge! :key => value

class MemoryCache
  def self.cache
    @cache ||= {}     $global_lock.do_something!
  end
end
Difficult to observe
with green threads
data = []
M.times do |m|
  Thread.new do
    N.times do |n|
      data << m * n
    end
  end
end
OK          NOT OK

             instance vars
method def
                String
 class def
                Array
class vars
                Hash
class WorkerTask
  def run
    @thread = Thread.new do
      50.times do
        digest = Digest::MD5.new
        @range.step(1024) do |idx|
          digest.update(@data[idx...idx+1024])
        end
      end
    end
  end
end
Other Concurrency
   Approaches
java.util.concurrent
require 'java'
java_import java.util.concurrent.Executors

@count = java.util.concurrent.atomic.AtomicInteger.new

def send_email(executor)
  executor.submit do
    puts "email #{@count.incrementAndGet} sent"
  end
end
executor = Executors.newCachedThreadPool
send_email(executor)



executor =
Executors.newFixedThreadPool(2)
loop do
  send_email(executor)
end
jetlang/jretlang
 http://code.google.com/p/jetlang/
https://github.com/reevesg/jretlang
require 'jretlang'

fiber = JRL::Fiber.new
channel = JRL::Channel.new
fiber.start

channel.subscribe_on_fiber(fiber) do |msg|
  puts msg
end

channel.publish "Hello"
Akka
     http://akka.io
http://j.mp/jruby-akka
require 'akka'

class HelloWord
  def hi
    puts "hello actor world"
  end
end

Actors.actorOf(HelloWord.new).hi
puts "initiating shutdown..."
Actors.delayedShutdown 1

Nick Sieger JRuby Concurrency EMRubyConf 2011