jack_rabbit 0.1.0-java → 0.2.0-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.
@@ -2,15 +2,23 @@ $:.push(File.expand_path('../../lib', __FILE__))
2
2
 
3
3
  require 'uri'
4
4
  require 'jack_rabbit'
5
+ require 'logger'
6
+ require 'thread'
7
+
8
+ $stdout.sync = true
9
+
10
+ Thread.abort_on_exception = true
5
11
 
6
12
  subscriptions = [
7
13
  # exchange key queue
8
14
  [ 'jackrabbitdev', 'consumer.test', 'consumer.test', {} ]
9
15
  ]
10
16
 
11
- consumer = JackRabbit::Consumer.new
17
+ consumer = JackRabbit::Consumer.new(Logger.new($stdout))
12
18
 
13
- consumer.connect([ URI.parse('amqp://guest:guest@localhost:5672/') ])
19
+ consumer.connect([
20
+ URI.parse('amqp://guest:guest@localhost:5672/')
21
+ ])
14
22
 
15
23
  subscriptions.each do |exchange, key, queue, options|
16
24
  consumer.subscribe(exchange, key, queue, options) do |header, message|
@@ -2,12 +2,21 @@ $:.push(File.expand_path('../../lib', __FILE__))
2
2
 
3
3
  require 'uri'
4
4
  require 'jack_rabbit'
5
+ require 'logger'
6
+ require 'thread'
5
7
 
6
- producer = JackRabbit::Producer.new
8
+ $stdout.sync = true
9
+
10
+ Thread.abort_on_exception = true
11
+
12
+ producer = JackRabbit::Producer.new(Logger.new($stdout))
7
13
 
8
14
  producer.connect(URI.parse('amqp://guest:guest@localhost:5672/'))
9
15
 
16
+ n = 0
10
17
  loop do
11
- puts producer.publish('jackrabbitdev', :direct, 'consumer.test', 'foo')
18
+ message = (n += 1).to_s
19
+ producer.publish('jackrabbitdev', :direct, 'consumer.test', message)
20
+ puts(message)
12
21
  sleep(1)
13
22
  end
@@ -0,0 +1,15 @@
1
+ module JackRabbit
2
+ module Backoff
3
+ MAX = 16 # seconds
4
+
5
+ def with_backoff(exception, f = ->(n) { n < MAX ? 2**n : MAX }, &block)
6
+ n = 0
7
+ begin
8
+ yield
9
+ rescue exception
10
+ sleep(n = f[n])
11
+ retry
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,56 @@
1
+ require 'jack_rabbit/subscription'
2
+ require 'jack_rabbit/logging'
3
+
4
+ module JackRabbit
5
+ class Channel
6
+ include Logging
7
+
8
+ EXCHANGE_OPTIONS = { durable: true, type: :direct }
9
+
10
+ QUEUE_OPTIONS = { durable: true }
11
+
12
+ def initialize(connection, options)
13
+ @connection, @options = connection, options
14
+ @subscriptions = []
15
+ end
16
+
17
+ def open
18
+ open_channel(@connection, @options)
19
+ self
20
+ end
21
+
22
+ def close
23
+ @channel.close
24
+ end
25
+
26
+ def subscribe(exchange, key, queue, options, &block)
27
+ sub = Subscription.new(self, exchange, key, queue, options, &block)
28
+ @subscriptions << sub
29
+ sub.declare
30
+ sub
31
+ end
32
+
33
+ def reopen
34
+ open_channel(@connection, @options)
35
+ @subscriptions.each { |sub| sub.declare }
36
+ end
37
+
38
+ def create_exchange(name, options)
39
+ @channel.exchange(name, EXCHANGE_OPTIONS.merge(options))
40
+ end
41
+
42
+ def create_queue(name, options)
43
+ @channel.queue(name, QUEUE_OPTIONS.merge(options))
44
+ end
45
+
46
+ private
47
+
48
+ def open_channel(connection, options)
49
+ debug('opening channel...')
50
+ channel = connection.create_channel
51
+ channel.prefetch(options[:prefetch]) if options[:prefetch]
52
+ channel.add_shutdown_listener { |_reason| connection.reconnect }
53
+ @channel = channel
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,20 @@
1
+ require 'jack_rabbit/connection'
2
+
3
+ module JackRabbit
4
+ module Client
5
+ private
6
+
7
+ def open_connection(uri, options)
8
+ Connection.new(uri, options)
9
+ .set_logger(@logger)
10
+ .open
11
+ end
12
+
13
+ def open_channel(connection, options)
14
+ connection
15
+ .channel(options)
16
+ .set_logger(@logger)
17
+ .open
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,65 @@
1
+ require 'hot_bunnies'
2
+ require 'jack_rabbit/backoff'
3
+ require 'jack_rabbit/channel'
4
+ require 'jack_rabbit/logging'
5
+
6
+ module JackRabbit
7
+ class Connection
8
+ include Backoff
9
+ include Logging
10
+
11
+ DEFAULT_OPTIONS = { connection_timeout: 5, heartbeat_interval: 5 }
12
+
13
+ def initialize(uri, options)
14
+ @uri, @options = uri, options.merge(connection_options(uri))
15
+ @channels = []
16
+ end
17
+
18
+ def open
19
+ open_connection(@uri, @options)
20
+ self
21
+ end
22
+
23
+ def close
24
+ @connection.close
25
+ end
26
+
27
+ def channel(options)
28
+ channel = Channel.new(self, options)
29
+ @channels << channel
30
+ channel
31
+ end
32
+
33
+ def reopen(reason)
34
+ debug('%s, reconnecting...' % reason.inspect)
35
+ open_connection(@uri, @options)
36
+ @channels.each { |channel| channel.reopen }
37
+ end
38
+
39
+ def create_channel
40
+ @connection.create_channel
41
+ end
42
+
43
+ private
44
+
45
+ def open_connection(uri, options)
46
+ connection =
47
+ with_backoff(Java::JavaNet::ConnectException) do
48
+ info('connecting to %s:%d...' % [ uri.host, uri.port ])
49
+ HotBunnies.connect(options)
50
+ end
51
+ connection.add_shutdown_listener { |reason| reopen(reason) }
52
+ @connection = connection
53
+ end
54
+
55
+ def connection_options(uri)
56
+ DEFAULT_OPTIONS.merge({
57
+ host: uri.host,
58
+ pass: uri.password,
59
+ port: uri.port,
60
+ user: uri.user,
61
+ vhost: uri.path
62
+ })
63
+ end
64
+ end
65
+ end
@@ -1,79 +1,35 @@
1
- require 'hot_bunnies'
2
- require 'jack_rabbit/message_header'
1
+ require 'jack_rabbit/client'
3
2
 
4
3
  module JackRabbit
5
4
  class Consumer
6
- EXCHANGE_OPTIONS = { durable: true, type: :direct }
7
- QUEUE_OPTIONS = { durable: true }
8
- SUBSCRIBE_OPTIONS = { blocking: false }
5
+ include Client
9
6
 
10
- def initialize
11
- @connections = []
12
- @channels = []
13
- @subscriptions = []
7
+ def initialize(logger = nil)
8
+ @logger = logger
14
9
  end
15
10
 
16
11
  def connect(uris, options = {})
17
- uris.inject(@connections) do |memo, uri|
18
- memo.push(open_connection(uri, options))
19
- end
12
+ @connections = uris.map { |uri| open_connection(uri, options) }
20
13
  end
21
14
 
22
15
  def subscribe(exchange, key, queue, options = {}, &block)
23
- channels = open_channels(options[:prefetch])
24
- bind_queues(channels, exchange, key, queue, options) do |meta, message|
25
- block.call(MessageHeader.new(meta), message)
16
+ @connections.each do |connection|
17
+ channel = open_channel(connection, options)
18
+ declare_subscription(channel, exchange, key, queue, options, &block)
26
19
  end
27
20
  end
28
21
 
29
22
  def disconnect
30
- @subscriptions.each(&:shutdown!)
31
- (@channels + @connections).each(&:close)
23
+ @connections.each { |connection| connection.close }
32
24
  end
33
25
 
34
26
  private
35
27
 
36
- def open_connection(uri, options)
37
- connection =
38
- HotBunnies.connect(options.merge(
39
- host: uri.host,
40
- pass: uri.password,
41
- port: uri.port,
42
- user: uri.user,
43
- vhost: uri.path
44
- ))
45
- connection.add_shutdown_listener { |_reason| exit! }
46
- connection
47
- end
48
-
49
- def open_channels(prefetch)
50
- @connections.inject(@channels) do |memo, connection|
51
- channel = connection.create_channel
52
- channel.add_shutdown_listener { |_reason| exit! }
53
- channel.prefetch = prefetch if prefetch
54
- memo.push(channel)
55
- end
56
- end
57
-
58
- def bind_queues(channels, exchange_name, key, queue_name, options, &block)
59
- channels.inject(@subscriptions) do |memo, channel|
60
- exchange = declare_exchange(channel, exchange_name, options)
61
- queue =
62
- bind_queue(channel, exchange, queue_name, key, options).tap do |q|
63
- q.subscribe(SUBSCRIBE_OPTIONS.merge(options), &block)
64
- end
65
- memo.push(queue)
66
- end
67
- end
68
-
69
- def bind_queue(channel, exchange, name, key, options)
28
+ def declare_subscription(channel, exchange, key, queue, options, &block)
70
29
  channel
71
- .queue(name, QUEUE_OPTIONS.merge(Hash(options[:queue])))
72
- .tap { |q| q.bind(exchange, { routing_key: key }) }
73
- end
74
-
75
- def declare_exchange(channel, name, options)
76
- channel.exchange(name, EXCHANGE_OPTIONS.merge(Hash(options[:exchange])))
30
+ .subscribe(exchange, key, queue, options, &block)
31
+ .set_logger(@logger)
77
32
  end
78
33
  end
79
34
  end
35
+
@@ -0,0 +1,24 @@
1
+ module JackRabbit
2
+ module Logging
3
+ TAG = '[jack_rabbit] '
4
+
5
+ def set_logger(logger)
6
+ @logger = logger
7
+ self
8
+ end
9
+
10
+ private
11
+
12
+ def debug(message)
13
+ log(:debug, message)
14
+ end
15
+
16
+ def info(message)
17
+ log(:info, message)
18
+ end
19
+
20
+ def log(severity, message)
21
+ @logger.send(severity, TAG + message) if @logger
22
+ end
23
+ end
24
+ end
@@ -1,50 +1,33 @@
1
- require 'hot_bunnies'
1
+ require 'jack_rabbit/backoff'
2
+ require 'jack_rabbit/client'
2
3
 
3
4
  module JackRabbit
4
5
  class Producer
5
- EXCHANGE_OPTIONS = { auto_delete: false, durable: true }
6
+ include Backoff
7
+ include Client
8
+ include Logging
6
9
 
7
- def connect(uri, options = {})
8
- @channel = (@connection = open_connection(uri, options)).create_channel
10
+ def initialize(logger = nil)
11
+ @logger = logger
9
12
  end
10
13
 
11
- def disconnect
12
- [ @channel, @connection ].each(&:close)
14
+ def connect(uri, options = {})
15
+ @connection = open_connection(uri, options)
16
+ @channel = open_channel(@connection, options)
13
17
  end
14
18
 
15
- def publish(exchange_name, exchange_type, routing_key, message, headers = {})
16
- with_exchange(@channel, exchange_name, exchange_type) do |exchange|
17
- exchange.publish(message, headers.merge(routing_key: routing_key))
19
+ def publish(exchange, type, key, message, headers = {})
20
+ with_backoff(Java::ComRabbitmqClient::AlreadyClosedException) do
21
+ debug('publishing to %s:%s with %s...' % [ type, exchange, key ])
22
+ @channel
23
+ .create_exchange(exchange, { type: type })
24
+ .publish(message, headers.merge(routing_key: key))
18
25
  end
19
26
  end
20
27
 
21
- private
22
-
23
- def open_connection(uri, options)
24
- connection =
25
- HotBunnies.connect(options.merge(
26
- host: uri.host,
27
- pass: uri.password,
28
- port: uri.port,
29
- user: uri.user,
30
- vhost: uri.path
31
- ))
32
- connection.add_shutdown_listener { |_reason| exit! }
33
- connection
34
- end
35
-
36
- def open_channel(connection)
37
- channel = connection.open_channel
38
- channel.add_shutdown_listener { |_reason| exit! }
39
- channel
40
- end
41
-
42
- def with_exchange(channel, exchange_name, exchange_type, &block)
43
- block.call(
44
- channel.exchange(exchange_name, EXCHANGE_OPTIONS.merge(
45
- type: exchange_type
46
- ))
47
- )
28
+ def disconnect
29
+ @channel.close
30
+ @connection.close
48
31
  end
49
32
  end
50
33
  end
@@ -0,0 +1,26 @@
1
+ require 'jack_rabbit/message_header'
2
+ require 'jack_rabbit/logging'
3
+
4
+ module JackRabbit
5
+ class Subscription
6
+ include Logging
7
+
8
+ DEFAULT_OPTIONS = { blocking: false }
9
+
10
+ def initialize(channel, exchange, key, queue, options, &block)
11
+ @channel = channel
12
+ @exchange, @key, @queue, @options = exchange, key, queue, options
13
+ @block = block
14
+ end
15
+
16
+ def declare
17
+ exchange = @channel.create_exchange(@exchange, @options)
18
+ queue = @channel.create_queue(@queue, @options)
19
+ queue.bind(exchange, { routing_key: @key })
20
+ @subscription =
21
+ queue.subscribe(DEFAULT_OPTIONS.merge(@options)) do |meta, message|
22
+ @block.call(MessageHeader.new(meta), message)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module JackRabbit
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: jack_rabbit
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.2.0
6
6
  platform: java
7
7
  authors:
8
8
  - Sebastian Ohm
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-21 00:00:00.000000000 Z
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hot_bunnies
@@ -43,9 +43,15 @@ files:
43
43
  - dev/producer.rb
44
44
  - jack_rabbit.gemspec
45
45
  - lib/jack_rabbit.rb
46
+ - lib/jack_rabbit/backoff.rb
47
+ - lib/jack_rabbit/channel.rb
48
+ - lib/jack_rabbit/client.rb
49
+ - lib/jack_rabbit/connection.rb
46
50
  - lib/jack_rabbit/consumer.rb
51
+ - lib/jack_rabbit/logging.rb
47
52
  - lib/jack_rabbit/message_header.rb
48
53
  - lib/jack_rabbit/producer.rb
54
+ - lib/jack_rabbit/subscription.rb
49
55
  - lib/jack_rabbit/version.rb
50
56
  homepage:
51
57
  licenses: []