2010-07-30

JRubyKaigi2010

I'll give a 20min. session talk on JRubyKaigi2010. (smart URL, isn't it?)

"JRuby Hacking Guide" - Aims; extracting what is where in JRuby source code, showing how those interacts when, and hacking/troubleshooting it by examples in 20 min.

Date: 8/28(Sat.) 13:00-18:00 (on the second day in RubyKaigi2010)

JRuby co-lead Charles O.Nutter and Thomas Enebo comes to Japan and have a Keynote. Can't wait to discuss with them including many Japanese developers who are interested in JRuby's future.

Are you planning to go RubyKaigi2010? Interested in JRuby's compilation details, optimization scheme and trouble shooting? See you there!

2010-07-28

Queue#pop is unfair in Ruby 1.9

Do you think Queue is fair?

"Fairness" here is, when two or more threads wait with Queue#pop, the control is sequentially passed from the thread for which it waits longest when Queue#push is invoked.

In this sense, Ruby 1.8 is "fair". Following script always dumps "[:go, :first]" for Ruby 1.8.

# http://gist.github.com/493930#file_gistfile1.rb
create_waiter = lambda { |name, command|
t = Thread.new {
p [command.pop, name]
}
Thread.pass until t.status == 'sleep'
t
}

50.times do
command = Queue.new
# create 3 waiters, and...
create_waiter.call(:first, command)
create_waiter.call(:second, command)
create_waiter.call(:third, command)
# and pushes a command.
command.push(:go)
# then try to consume the command by a subsequent thread
Thread.new {
p [command.pop, :LATER]
}
end

In contrast to this, Ruby 1.9 sometimes dumps "[:go, :LATER]" because Queue#pop became unfair from Ruby 1.9.

To tell the truth, there might be no use in making Queue fair because Mutex#lock is unfair in Ruby. However, Queue#pop implementation in Ruby 1.9 is almost fair so if there's a good solution... Anyone?

Anyway, person who is using 1.8 Queue as a thread scheduler should care this change. My typical usage was as follows.

# http://gist.github.com/430066
require 'thread'

q = Queue.new
t1 = Thread.new {
p [:t1, q.pop]
q.push(:t1)
}

q.push(:main)
p [:main, q.pop]

EDITED ADD (8/1): You should wait for the created thread sleeping like the first script on this page.

By the way, Queue#pop in JRuby (both 1.8 and 1.9 modes) is unfair as well but slightly different from Ruby 1.9; only the main thread break in the scheduler. It's written by @mentalguy who is the author or fastthread for Ruby 1.8.