hot_bunnies 1.1.2-java

Sign up to get free protection for your applications and to get access to all the features.
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
+