JRuby ConcurrencyNick SiegerEMRubyConf @ RailsConf 2011
MentalModel
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 endend
How could this code fail?
class ExpensiveToCreate def self.instance unless defined?(@instance) @instance = ExpensiveToCreate.new end endend
class ExpensiveToCreate def self.instance unless defined?(@instance) @instance = ExpensiveToCreate.allocate @instance.initialize # big pause here @instance end endend
How could this code fail?
T1T2
Avoid shared mutable state,lazy initialization
MutableConstant.merge! :key => value
class MemoryCache def self.cache @cache ||= {} endend
$global_lock.do_something!
Difficult to observewith green threads
data = [] M.times do |m| Thread.new do N.times do |n| data << m * n end end end
OK NOT OK
method defclass def
class vars
instance varsStringArrayHash
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 endend
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" endend
executor = Executors.newCachedThreadPoolsend_email(executor)
executor = Executors.newFixedThreadPool(2)loop do send_email(executor)end
jetlang/jretlanghttp://code.google.com/p/jetlang/
https://github.com/reevesg/jretlang
require 'jretlang'
fiber = JRL::Fiber.newchannel = JRL::Channel.newfiber.start
channel.subscribe_on_fiber(fiber) do |msg| puts msgend
channel.publish "Hello"
Akkahttp://akka.io
http://j.mp/jruby-akka
require 'akka'
class HelloWord def hi puts "hello actor world" endend
Actors.actorOf(HelloWord.new).hiputs "initiating shutdown..."Actors.delayedShutdown 1