Yea! My first gem ever released!
[YUCK! It was a disaster in a few ways! Don't look at this! It's hideous! There's a new jruby_producer_consumer gem on gemcutter that is slightly different from this in that it works. Ignore the stuff below.]
[In working on a threaded JRuby-based MARC-to-Solr project, I realized that my threading stuff was...ugly. And I didn't really understand it. So I dug in today and wrote this.]
I’ve just pushed to Gemcutter my first gem — a JRuby-only producer/consumer class that works with anything that provides #each called jruby_producer_consumer.
It’s JRuby-only because it uses (a) A blocking queue implemenation that’s native Java, and (b) threading, which isn’t a huge win under regular Ruby.
There’s no testing there because I’m not sure how to test threaded stuff
It is, I hope, easy to use:
- require 'rubygems'
- require 'jruby_producer_consumer'
- # Create a ProducerConsumer. Arguments are anything that implements #each
- # and the size for the underlying queue. For the former, I'll just use a Range object.
- eachable = 1..10
- queuesize = 3
- pc = ProducerConsumer.new(eachable, queuesize)
- # Just a method to show what happens
- def sample (consumerid, x)
- puts "Consumer #{consumerid}: consuming #{x}"
- sleep 1 # otherwise this'll finsish before I can create multiple consumers
- end
- # Create three consumers. You can pass any number of args to
- # #consumer, and must pass a block whose arguments are the
- # object returned by eachable#each and those args back.
- ['A', 'B', 'C'].each do |consumerid|
- pc.consumer(consumerid) do |x, consumerid|
- sample(consumerid, x)
- end
- end
- # OUTPUT
- # Consumer A: consuming 1
- # Consumer B: consuming 2
- # Consumer C: consuming 3
- # Consumer A: consuming 4
- # Consumer B: consuming 5
- # Consumer C: consuming 6
- # Consumer B: consuming 7
- # Consumer A: consuming 8
- # Consumer C: consuming 9
- # Consumer B: consuming 10