hot_bunnies 1.1.2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm --create use jruby-1.6.2@hot_bunnies
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ gem 'jruby-openssl'
6
+ gem 'rake'
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+
5
+
6
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,36 @@
1
+ $: << 'lib'
2
+
3
+ require 'hot_bunnies'
4
+
5
+
6
+ connection = HotBunnies.connect(:host => 'localhost')
7
+ channel = connection.create_channel
8
+ channel.prefetch = 10
9
+
10
+ exchange = channel.exchange('test', :type => :direct)
11
+
12
+ queue = channel.queue('hello.world')
13
+ queue.bind(exchange, :routing_key => 'xyz')
14
+ queue.purge
15
+
16
+ 100.times do |i|
17
+ exchange.publish("hello world! #{i}", :routing_key => 'xyz')
18
+ end
19
+
20
+ exchange.publish("POISON!", :routing_key => 'xyz')
21
+
22
+ subscription = queue.subscribe(:ack => true)
23
+ subscription.each(:blocking => true) do |headers, msg|
24
+ puts msg
25
+ headers.ack
26
+ if msg == "POISON!"
27
+ :cancel
28
+ end
29
+ end
30
+
31
+ puts "ALL DONE!"
32
+
33
+ at_exit do
34
+ channel.close
35
+ connection.close
36
+ end
@@ -0,0 +1,32 @@
1
+ $: << 'lib'
2
+
3
+ require 'hot_bunnies'
4
+
5
+
6
+ connection = HotBunnies.connect(:host => 'localhost')
7
+ channel = connection.create_channel
8
+ channel.prefetch = 10
9
+
10
+ exchange = channel.exchange('test', :type => :direct)
11
+
12
+ queue = channel.queue('hello.world')
13
+ queue.bind(exchange, :routing_key => 'xyz')
14
+ queue.purge
15
+
16
+ subscription = queue.subscribe(:ack => true, :blocking => false) do |headers, msg|
17
+ puts msg
18
+ headers.ack
19
+ end
20
+
21
+ 100.times do |i|
22
+ exchange.publish("hello world! #{i}", :routing_key => 'xyz')
23
+ end
24
+
25
+ subscription.cancel
26
+
27
+ puts "ALMOST ALL DONE!"
28
+
29
+ at_exit do
30
+ channel.close
31
+ connection.close
32
+ end
@@ -0,0 +1,38 @@
1
+ $: << 'lib'
2
+
3
+ require 'hot_bunnies'
4
+
5
+ import java.util.concurrent.Executors
6
+
7
+
8
+ connection = HotBunnies.connect(:host => 'localhost')
9
+ channel = connection.create_channel
10
+ channel.prefetch = 10
11
+
12
+ exchange = channel.exchange('test', :type => :direct)
13
+
14
+ queue = channel.queue('hello.world')
15
+ queue.bind(exchange, :routing_key => 'xyz')
16
+ queue.purge
17
+
18
+ thread_pool = Executors.new_fixed_thread_pool(3)
19
+
20
+ subscription = queue.subscribe(:ack => true)
21
+ subscription.each(:blocking => false, :executor => thread_pool) do |headers, msg|
22
+ puts msg
23
+ headers.ack
24
+ end
25
+
26
+ 100.times do |i|
27
+ exchange.publish("hello world! #{i}", :routing_key => 'xyz')
28
+ end
29
+
30
+ thread_pool.shutdown_now
31
+ subscription.cancel
32
+
33
+ puts "ALMOST ALL DONE!"
34
+
35
+ at_exit do
36
+ channel.close
37
+ connection.close
38
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ $: << File.expand_path('../lib', __FILE__)
4
+
5
+ require 'hot_bunnies/version'
6
+
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = 'hot_bunnies'
10
+ s.version = HotBunnies::VERSION
11
+ s.platform = 'java'
12
+ s.authors = ['Theo Hultberg']
13
+ s.email = ['theo@burtcorp.com']
14
+ s.homepage = 'http://github.com/iconara/hot_bunnies'
15
+ s.summary = %q{Ruby wrapper for the RabbitMQ Java driver}
16
+ s.description = %q{A object oriented interface to RabbitMQ that uses the Java driver under the hood}
17
+
18
+ s.rubyforge_project = 'hot_bunnies'
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ # s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ # s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = %w(lib)
24
+ end
Binary file
Binary file
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module HotBunnies
4
+ module Channel
5
+ def queue(name, options={})
6
+ Queue.new(self, name, options)
7
+ end
8
+
9
+ def exchange(name, options={})
10
+ Exchange.new(self, name, options)
11
+ end
12
+
13
+ def qos(options={})
14
+ if options.size == 1 && options[:prefetch_count]
15
+ then basic_qos(options[:prefetch_count])
16
+ else basic_qos(options.fetch(:prefetch_size, 0), options.fetch(:prefetch_count, 0), options.fetch(:global, false))
17
+ end
18
+ end
19
+
20
+ def prefetch=(n)
21
+ qos(:prefetch_count => n)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ module HotBunnies
4
+ class Exchange
5
+ attr_reader :name, :channel
6
+
7
+ def initialize(channel, name, options={})
8
+ @channel = channel
9
+ @name = name
10
+ @options = {:type => :fanout, :durable => false, :auto_delete => false, :internal => false, :passive => false}.merge(options)
11
+ declare!
12
+ end
13
+
14
+ def publish(body, options={})
15
+ options = {:routing_key => '', :mandatory => false, :immediate => false}.merge(options)
16
+ @channel.basic_publish(@name, options[:routing_key], options[:mandatory], options[:immediate], nil, body.to_java_bytes)
17
+ end
18
+
19
+ def delete(options={})
20
+ @channel.exchange_delete(@name, options.fetch(:if_unused, false))
21
+ end
22
+
23
+ private
24
+
25
+ def declare!
26
+ unless @name == ''
27
+ if @options[:passive]
28
+ then @channel.exchange_declare_passive(@name)
29
+ else @channel.exchange_declare(@name, @options[:type].to_s, @options[:durable], @options[:auto_delete], @options[:internal], nil)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,171 @@
1
+ # encoding: utf-8
2
+
3
+ module HotBunnies
4
+ class Queue
5
+ attr_reader :name, :channel
6
+
7
+ def initialize(channel, name, options={})
8
+ @channel = channel
9
+ @name = name
10
+ @options = {:durable => false, :exclusive => false, :auto_delete => false, :passive => false}.merge(options)
11
+ declare!
12
+ end
13
+
14
+ def bind(exchange, options={})
15
+ exchange_name = if exchange.respond_to?(:name) then exchange.name else exchange.to_s end
16
+ @channel.queue_bind(@name, exchange_name, options.fetch(:routing_key, ''))
17
+ end
18
+
19
+ def unbind(exchange, options={})
20
+ exchange_name = if exchange.respond_to?(:name) then exchange.name else exchange.to_s end
21
+ @channel.queue_unbind(@name, exchange_name, options.fetch(:routing_key, ''))
22
+ end
23
+
24
+ def delete
25
+ @channel.queue_delete(@name)
26
+ end
27
+
28
+ def purge
29
+ @channel.queue_purge(@name)
30
+ end
31
+
32
+ def get(options={})
33
+ response = @channel.basic_get(@name, !options.fetch(:ack, false))
34
+ if response
35
+ then [Headers.new(@channel, nil, response.envelope, response.props), String.from_java_bytes(response.body)]
36
+ else nil
37
+ end
38
+ end
39
+
40
+ def subscribe(options={}, &block)
41
+ subscription = Subscription.new(@channel, @name, options)
42
+ subscription.each(options, &block) if block
43
+ subscription
44
+ end
45
+
46
+ def status
47
+ response = @channel.queue_declare_passive(@name)
48
+ [response.message_count, response.consumer_count]
49
+ end
50
+
51
+ private
52
+
53
+ def declare!
54
+ response = if @options[:passive]
55
+ then @channel.queue_declare_passive(@name)
56
+ else @channel.queue_declare(@name, @options[:durable], @options[:exclusive], @options[:auto_delete], nil)
57
+ end
58
+ @name = response.queue
59
+ end
60
+
61
+ class Subscription
62
+ def initialize(channel, queue_name, options={})
63
+ @channel = channel
64
+ @queue_name = queue_name
65
+ @ack = options.fetch(:ack, false)
66
+ end
67
+
68
+ def each(options={}, &block)
69
+ raise 'The subscription already has a message listener' if @subscriber
70
+ if options.fetch(:blocking, true)
71
+ run(&block)
72
+ else
73
+ if options[:executor]
74
+ @shut_down_executor = false
75
+ @executor = options[:executor]
76
+ else
77
+ @shut_down_executor = true
78
+ @executor = java.util.concurrent.Executors.new_single_thread_executor
79
+ end
80
+ @executor.submit { run(&block) }
81
+ end
82
+ end
83
+
84
+ def cancel
85
+ raise 'Can\'t cancel: the subscriber haven\'t received an OK yet' if !@subscriber || !@subscriber.consumer_tag
86
+ @channel.basic_cancel(@subscriber.consumer_tag)
87
+ @executor.shutdown_now if @executor && @shut_down_executor
88
+ end
89
+
90
+ private
91
+
92
+ def run(&block)
93
+ @subscriber = BlockingSubscriber.new(@channel, self)
94
+ @channel.basic_consume(@queue_name, !@ack, @subscriber.consumer)
95
+ @subscriber.on_message(&block)
96
+ end
97
+ end
98
+
99
+ class Headers
100
+ def initialize(channel, consumer_tag, envelope, properties)
101
+ @channel = channel
102
+ @consumer_tag = consumer_tag
103
+ @envelope = envelope
104
+ @properties = properties
105
+ end
106
+
107
+ def ack(options={})
108
+ @channel.basic_ack(delivery_tag, options.fetch(:multiple, false))
109
+ end
110
+
111
+ def reject(options={})
112
+ @channel.basic_ack(delivery_tag, options.fetch(:requeue, false))
113
+ end
114
+
115
+ def delivery_tag
116
+ @envelope.delivery_tag
117
+ end
118
+ end
119
+
120
+ module Subscriber
121
+ def start
122
+ # to be implemented by the host class
123
+ end
124
+
125
+ def on_message(&block)
126
+ raise ArgumentError, 'Message listener already registered for this subscriber' if @subscriber
127
+ @subscriber = block
128
+ start
129
+ end
130
+
131
+ def handle_message(consumer_tag, envelope, properties, body_bytes)
132
+ body = String.from_java_bytes(body_bytes)
133
+ case @subscriber.arity
134
+ when 2 then @subscriber.call(Headers.new(@channel, consumer_tag, envelope, properties), body)
135
+ when 1 then @subscriber.call(body)
136
+ else raise ArgumentError, 'Consumer callback wants no arguments'
137
+ end
138
+ end
139
+ end
140
+
141
+ class BlockingSubscriber
142
+ include Subscriber
143
+
144
+ attr_reader :consumer
145
+
146
+ def initialize(channel, subscription)
147
+ @channel = channel
148
+ @subscription = subscription
149
+ @consumer = QueueingConsumer.new(@channel)
150
+ end
151
+
152
+ def consumer_tag
153
+ @consumer.consumer_tag
154
+ end
155
+
156
+ def start
157
+ super
158
+ while delivery = @consumer.next_delivery
159
+ result = handle_message(@consumer.consumer_tag, delivery.envelope, delivery.properties, delivery.body)
160
+ if result == :cancel
161
+ @subscription.cancel
162
+ while delivery = @consumer.next_delivery(0)
163
+ handle_message(@consumer.consumer_tag, delivery.envelope, delivery.properties, delivery.body)
164
+ end
165
+ break
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module HotBunnies
4
+ VERSION = '1.1.2'
5
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ require 'java'
4
+ require 'ext/commons-io'
5
+ require 'ext/rabbitmq-client'
6
+
7
+
8
+ module HotBunnies
9
+ import com.rabbitmq.client.ConnectionFactory
10
+ import com.rabbitmq.client.Connection
11
+ import com.rabbitmq.client.Channel
12
+ import com.rabbitmq.client.DefaultConsumer
13
+ import com.rabbitmq.client.QueueingConsumer
14
+
15
+ CONNECTION_PROPERTIES = [:host, :port, :virtual_host, :connection_timeout, :username, :password]
16
+
17
+ def self.connect(options={})
18
+ cf = ConnectionFactory.new
19
+ CONNECTION_PROPERTIES.each do |property|
20
+ if options[property]
21
+ cf.send("#{property}=".to_sym, options[property])
22
+ end
23
+ end
24
+ cf.new_connection
25
+ end
26
+ end
27
+
28
+ require 'hot_bunnies/channel'
29
+ require 'hot_bunnies/queue'
30
+ require 'hot_bunnies/exchange'
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hot_bunnies
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.1.2
6
+ platform: java
7
+ authors:
8
+ - Theo Hultberg
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-07-13 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: A object oriented interface to RabbitMQ that uses the Java driver under the hood
18
+ email:
19
+ - theo@burtcorp.com
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - .gitignore
28
+ - .rvmrc
29
+ - Gemfile
30
+ - Rakefile
31
+ - examples/blocking_subscription.rb
32
+ - examples/non_blocking_subscription.rb
33
+ - examples/non_blocking_subscription_with_executor.rb
34
+ - hot_bunnies.gemspec
35
+ - lib/ext/commons-io.jar
36
+ - lib/ext/rabbitmq-client.jar
37
+ - lib/hot_bunnies.rb
38
+ - lib/hot_bunnies/channel.rb
39
+ - lib/hot_bunnies/exchange.rb
40
+ - lib/hot_bunnies/queue.rb
41
+ - lib/hot_bunnies/version.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/iconara/hot_bunnies
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project: hot_bunnies
66
+ rubygems_version: 1.5.2
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Ruby wrapper for the RabbitMQ Java driver
70
+ test_files: []
71
+