rt-tackle 0.9 → 1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b51e7b8dd21855f3c3a88d9da4be12c54a715d69
4
- data.tar.gz: b4efab4ce923c03a8891099568192400ca085db4
3
+ metadata.gz: de0f2580c2937c203f50d01d0a8e7a66c8ad4cbe
4
+ data.tar.gz: 249a5fabc8c8dc812a69d8541ae3ab7c8e046d3e
5
5
  SHA512:
6
- metadata.gz: 37f17e2b31c9b00c927dd3611ddc24b95b82e348f8ae33534b29df4bdc275507cc63b04df991ba26b42ae13f58f366e00e4771c06d8b3cc684b92e5d86623c69
7
- data.tar.gz: 3e6743290efe3377fe2842c9930ffe86b5322e3ac7247d24860560cb5efaed2914936bdfb32c603ca888c94107a989e4d673d61def947ee95b94c3112711dc92
6
+ metadata.gz: 784cb5cfec47ace9f60d6ddabdb5b7d117f31e76cba8c38b6960b318ca73cca851ec39f5d84c16f64df9485db5b63b24db467c83f89e155e80aab007a8712b3b
7
+ data.tar.gz: 099fac7e24bc267a4c6556e1706c46fde7d823a007215b66e5842d077add917b48d8830d2b75aa50d0efb69a946b31fa1a7e11bdc765db90e3f3a7b5ac40ddc8
data/README.md CHANGED
@@ -125,69 +125,6 @@ Tackle.consume(options) do |message|
125
125
  end
126
126
  ```
127
127
 
128
- ### [DEPRECATED] Subscribe to an exchange
129
-
130
- **Deprecation notice:** For newer projects please use `Tackle.consume`.
131
-
132
- To consume messages from an exchange, do the following:
133
-
134
- ```ruby
135
- require "tackle"
136
-
137
- options = {
138
- :url => "amqp://localhost",
139
- :exchange => "test-exchange",
140
- :routing_key => "test-messages",
141
- :queue => "test-queue"
142
- }
143
-
144
- Tackle.subscribe(options) do |message|
145
- puts message
146
- end
147
- ```
148
-
149
- By default, tackle will retry any message that fails to be consumed. To
150
- configure the retry limit and the delay in which the messages will be retried,
151
- do the following:
152
-
153
- ```ruby
154
- require "tackle"
155
-
156
- options = {
157
- :url => "amqp://localhost",
158
- :exchange => "test-exchange",
159
- :routing_key => "test-messages",
160
- :queue => "test-queue",
161
- :retry_limit => 8,
162
- :retry_delay => 30
163
- }
164
-
165
- Tackle.subscribe(options) do |message|
166
- puts message
167
- end
168
- ```
169
-
170
- Tackle uses the `STDOUT` by default to trace the state of incoming messages. You
171
- can pass a dedicated logger to the `subscribe` method to redirect the output:
172
-
173
- ```ruby
174
- require "tackle"
175
-
176
- options = {
177
- :url => "amqp://localhost",
178
- :exchange => "test-exchange",
179
- :routing_key => "test-messages",
180
- :queue => "test-queue",
181
- :retry_limit => 8,
182
- :retry_delay => 30,
183
- :logger => Logger.new("subscribe.log")
184
- }
185
-
186
- Tackle.subscribe(options) do |message|
187
- puts message
188
- end
189
- ```
190
-
191
128
  ## Development
192
129
 
193
130
  After checking out the repo, run `bin/setup` to install dependencies. Then,
@@ -0,0 +1,41 @@
1
+ module Tackle
2
+ class Connection
3
+ attr_reader :channel
4
+
5
+ def initialize(amqp_url, exception_handler, logger)
6
+ @amqp_url = amqp_url
7
+ @exception_handler = exception_handler
8
+ @logger = logger
9
+
10
+ connect
11
+ end
12
+
13
+ def connect
14
+ @logger.info("Connecting to RabbitMQ")
15
+
16
+ @connection = Bunny.new(@amqp_url)
17
+ @connection.start
18
+
19
+ @logger.info("Connected to RabbitMQ")
20
+
21
+ @channel = @connection.create_channel
22
+ @channel.prefetch(1)
23
+ @channel.on_uncaught_exception(&@exception_handler)
24
+
25
+ @logger.info("Connected to channel")
26
+ rescue StandardError => ex
27
+ @logger.error("Error while connecting to RabbitMQ message='#{ex}'")
28
+
29
+ raise ex
30
+ end
31
+
32
+ def close
33
+ @channel.close
34
+ @logger.info("Closed channel")
35
+
36
+ @connection.close
37
+ @logger.info("Closed connection to RabbitMQ")
38
+ end
39
+
40
+ end
41
+ end
@@ -1,6 +1,5 @@
1
1
  module Tackle
2
2
  require_relative "consumer/params"
3
- require_relative "consumer/connection"
4
3
  require_relative "consumer/message"
5
4
  require_relative "consumer/exchange"
6
5
 
@@ -19,7 +18,7 @@ module Tackle
19
18
  end
20
19
 
21
20
  def setup_rabbit_connections
22
- @connection = Connection.new(@params.amqp_url, @params.exception_handler, @logger)
21
+ @connection = Tackle::Connection.new(@params.amqp_url, @params.exception_handler, @logger)
23
22
 
24
23
  @exchange = Exchange.new(@params.service, @params.routing_key, @connection, @logger)
25
24
  @main_queue = MainQueue.new(@exchange, @connection, @logger)
@@ -1,49 +1,25 @@
1
1
  module Tackle
2
2
  class Publisher
3
- include Tackle::TackleLogger
4
3
 
5
- def initialize(exchange_name, routing_key, url, logger)
4
+ def initialize(url, exchange_name, routing_key, logger)
5
+ @url = url
6
6
  @exchange_name = exchange_name
7
7
  @routing_key = routing_key
8
- @url = url
9
8
  @logger = logger
10
9
  end
11
10
 
12
11
  def publish(message)
13
- tackle_log("Publishing message started exchange='#{@exchange_name}' routing_key='#{@routing_key}'")
14
-
15
- with_rabbit_connection do |conn|
16
- channel = conn.create_channel
17
- tackle_log("Created a communication channel")
18
-
19
- exchange = channel.direct(@exchange_name, :durable => true)
20
- tackle_log("Declared the exchange")
21
-
22
- exchange.publish(message, :routing_key => @routing_key, :persistent => true)
23
- end
24
-
25
- tackle_log("Publishing message finished exchange='#{@exchange_name}' routing_key='#{@routing_key}'")
26
- end
27
-
28
- private
29
-
30
- def with_rabbit_connection
31
- tackle_log("Establishing rabbit connection")
12
+ connection = Tackle::Connection.new(@url, nil, @logger)
32
13
 
33
- conn = Bunny.new(@url)
34
- conn.start
14
+ @logger.info("Declaring exchange='#{@exchange_name}'")
15
+ exchange = connection.channel.direct(@exchange_name, :durable => true)
16
+ @logger.info("Declared exchange='#{@exchange_name}'")
35
17
 
36
- yield(conn)
37
-
38
- tackle_log("Established rabbit connection")
39
- rescue StandardError => ex
40
- tackle_log("An exception occured while sending the message exception='#{ex.class.name}' message='#{ex.message}'")
41
-
42
- raise ex
18
+ @logger.info("Publishing message exchange='#{@exchange_name}' routing_key='#{@routing_key}'")
19
+ exchange.publish(message, :routing_key => @routing_key, :persistent => true)
20
+ @logger.info("Publishing message finished exchange='#{@exchange_name}' routing_key='#{@routing_key}'")
43
21
  ensure
44
- tackle_log("Clossing rabbit connection")
45
-
46
- conn.close if conn
22
+ connection.close
47
23
  end
48
24
 
49
25
  end
@@ -1,3 +1,3 @@
1
1
  module Tackle
2
- VERSION = "0.9"
2
+ VERSION = "1.0"
3
3
  end
data/lib/tackle.rb CHANGED
@@ -1,54 +1,27 @@
1
1
  require "tackle/version"
2
+ require "bunny"
3
+ require "logger"
2
4
 
3
5
  module Tackle
4
- require "tackle/worker"
6
+ require "tackle/connection"
5
7
  require "tackle/publisher"
6
8
  require "tackle/consumer"
7
9
 
8
- def self.consume(params = {}, &block)
10
+ module_function
11
+
12
+ def consume(params = {}, &block)
9
13
  params = Tackle::Consumer::Params.new(params)
10
14
  consumer = Tackle::Consumer.new(params)
11
15
 
12
16
  consumer.subscribe(&block)
13
17
  end
14
18
 
15
- # deprecated
16
- def self.subscribe(options = {}, &block)
17
- # required
18
- exchange_name = options.fetch(:exchange)
19
- routing_key = options.fetch(:routing_key)
20
- queue_name = options.fetch(:queue)
21
-
22
- # optional
23
- amqp_url = options[:url]
24
- retry_limit = options[:retry_limit]
25
- retry_delay = options[:retry_delay]
26
- logger = options[:logger]
27
- on_uncaught_exception = options[:on_uncaught_exception]
28
-
29
- worker = Tackle::Worker.new(exchange_name,
30
- routing_key,
31
- queue_name,
32
- :url => amqp_url,
33
- :retry_limit => retry_limit,
34
- :retry_delay => retry_delay,
35
- :logger => logger,
36
- :on_uncaught_exception => on_uncaught_exception)
37
-
38
- worker.subscribe(&block)
39
- end
40
-
41
- def self.publish(message, options = {})
42
- # required
43
- exchange_name = options.fetch(:exchange)
44
- routing_key = options.fetch(:routing_key)
45
-
46
- # optional
47
- amqp_url = options[:url] || "amqp://localhost:5672"
48
- logger = options[:logger] || Logger.new(STDOUT)
49
-
50
- publisher = Tackle::Publisher.new(exchange_name, routing_key, amqp_url, logger)
19
+ def publish(message, options = {})
20
+ url = options.fetch(:url)
21
+ exchange = options.fetch(:exchange)
22
+ routing_key = options.fetch(:routing_key)
23
+ logger = options.fetch(:logger, Logger.new(STDOUT))
51
24
 
52
- publisher.publish(message)
25
+ Tackle::Publisher.new(url, exchange, routing_key, logger).publish(message)
53
26
  end
54
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rt-tackle
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.9'
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rendered Text
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-09-07 00:00:00.000000000 Z
11
+ date: 2016-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny
@@ -96,8 +96,8 @@ files:
96
96
  - bin/setup
97
97
  - docs/consumer.png
98
98
  - lib/tackle.rb
99
+ - lib/tackle/connection.rb
99
100
  - lib/tackle/consumer.rb
100
- - lib/tackle/consumer/connection.rb
101
101
  - lib/tackle/consumer/dead_queue.rb
102
102
  - lib/tackle/consumer/delay_queue.rb
103
103
  - lib/tackle/consumer/exchange.rb
@@ -105,12 +105,8 @@ files:
105
105
  - lib/tackle/consumer/message.rb
106
106
  - lib/tackle/consumer/params.rb
107
107
  - lib/tackle/consumer/queue.rb
108
- - lib/tackle/delayed_retry.rb
109
108
  - lib/tackle/publisher.rb
110
- - lib/tackle/rabbit.rb
111
- - lib/tackle/tackle_logger.rb
112
109
  - lib/tackle/version.rb
113
- - lib/tackle/worker.rb
114
110
  - reset_rabbit.sh
115
111
  - tackle.gemspec
116
112
  homepage: https://semaphoreci.com
@@ -1,43 +0,0 @@
1
- module Tackle
2
- class Consumer
3
- class Connection
4
- attr_reader :channel
5
-
6
- def initialize(amqp_url, exception_handler, logger)
7
- @amqp_url = amqp_url
8
- @exception_handler = exception_handler
9
- @logger = logger
10
-
11
- connect
12
- end
13
-
14
- def connect
15
- @logger.info("Connecting to RabbitMQ")
16
-
17
- @connection = Bunny.new(@amqp_url)
18
- @connection.start
19
-
20
- @logger.info("Connected to RabbitMQ")
21
-
22
- @channel = @connection.create_channel
23
- @channel.prefetch(1)
24
- @channel.on_uncaught_exception(&@exception_handler)
25
-
26
- @logger.info("Connected to channel")
27
- rescue StandardError => ex
28
- @logger.error("Error while connecting to RabbitMQ message='#{ex}'")
29
-
30
- raise ex
31
- end
32
-
33
- def close
34
- @channel.close
35
- @logger.info("Closed channel")
36
-
37
- @connection.close
38
- @logger.info("Closed connection to RabbitMQ")
39
- end
40
-
41
- end
42
- end
43
- end
@@ -1,36 +0,0 @@
1
- require "tackle/tackle_logger"
2
-
3
- module Tackle
4
-
5
- class DelayedRetry
6
- include Tackle::TackleLogger
7
-
8
- def initialize(dead_letter_queue, properties, payload, retry_limit, logger)
9
- @dead_letter_queue = dead_letter_queue
10
- @properties = properties
11
- @payload = payload
12
- @retry_limit = retry_limit
13
- @logger = logger
14
- end
15
-
16
- def schedule_retry
17
- if retry_count < @retry_limit
18
- tackle_log("Adding message to retry queue for retry #{retry_count + 1}/#{@retry_limit}")
19
- @dead_letter_queue.publish(@payload, :headers => {:retry_count => retry_count + 1})
20
- else
21
- tackle_log("Reached #{retry_count} retries. Discarding message.")
22
- end
23
- end
24
-
25
- private
26
-
27
- def retry_count
28
- if @properties.headers && @properties.headers["retry_count"]
29
- @properties.headers["retry_count"]
30
- else
31
- 0
32
- end
33
- end
34
-
35
- end
36
- end
data/lib/tackle/rabbit.rb DELETED
@@ -1,87 +0,0 @@
1
- require "bunny"
2
- require "tackle/tackle_logger"
3
-
4
- module Tackle
5
-
6
- class Rabbit
7
- include Tackle::TackleLogger
8
-
9
- attr_reader :channel, :dead_letter_queue, :queue, :exchange
10
-
11
- def initialize(exchange_name, routing_key, queue_name, amqp_url, retry_delay, logger)
12
- @exchange_name = exchange_name
13
- @routing_key = routing_key
14
- @queue_name = queue_name
15
- @amqp_url = amqp_url
16
- @retry_delay = retry_delay
17
- @logger = logger
18
- end
19
-
20
- def connect
21
- @conn = Bunny.new(@amqp_url)
22
- @conn.start
23
- tackle_log("Connected to RabbitMQ")
24
-
25
- @channel = @conn.create_channel
26
- @channel.prefetch(1)
27
-
28
- tackle_log("Connected to channel")
29
- connect_queue
30
- connect_dead_letter_queue
31
- rescue StandardError => ex
32
- tackle_log("An exception occured while connecting to the server message='#{ex.message}'")
33
-
34
- raise ex
35
- end
36
-
37
- def on_uncaught_exception(blk)
38
- @channel.on_uncaught_exception(&blk)
39
- end
40
-
41
- def close
42
- @channel.close
43
- tackle_log("Closed channel")
44
- @conn.close
45
- tackle_log("Closed connection to RabbitMQ")
46
- end
47
-
48
- def dead_letter_exchange_name
49
- "#{@exchange_name}.dead_letter_exchange"
50
- end
51
-
52
- def dead_letter_queue_name
53
- "#{@queue_name}_dead_letters"
54
- end
55
-
56
- private
57
-
58
- def connect_queue
59
- @exchange = @channel.direct(@exchange_name, :durable => true)
60
- tackle_log("Connected to exchange '#{@exchange_name}'")
61
-
62
- @queue = @channel.queue(@queue_name, :durable => true).bind(@exchange, :routing_key => @routing_key)
63
-
64
- tackle_log("Connected to queue '#{@queue_name}' with routing key '#{@routing_key}'")
65
- end
66
-
67
- def connect_dead_letter_queue
68
- tackle_log("Connected to dead letter exchange '#{dead_letter_exchange_name}'")
69
-
70
- dead_letter_exchange = @channel.fanout(dead_letter_exchange_name)
71
-
72
- queue_options = {
73
- :durable => true,
74
- :arguments => {
75
- "x-dead-letter-exchange" => @exchange_name,
76
- "x-dead-letter-routing-key" => @routing_key,
77
- "x-message-ttl" => @retry_delay
78
- }
79
- }
80
-
81
- @dead_letter_queue = @channel.queue(dead_letter_queue_name, queue_options).bind(dead_letter_exchange, :routing_key => @routing_key)
82
-
83
- tackle_log("Connected to dead letter queue '#{dead_letter_queue_name}'")
84
- end
85
-
86
- end
87
- end
@@ -1,13 +0,0 @@
1
- module Tackle
2
-
3
- module TackleLogger
4
-
5
- def tackle_log(message)
6
- pid = Process.pid
7
-
8
- whole_message = "tackle - pid=#{pid} message=#{message}"
9
-
10
- @logger.info(whole_message)
11
- end
12
- end
13
- end
data/lib/tackle/worker.rb DELETED
@@ -1,86 +0,0 @@
1
- require "tackle/rabbit"
2
- require "tackle/delayed_retry"
3
-
4
- module Tackle
5
- class Worker
6
- include Tackle::TackleLogger
7
-
8
- attr_reader :rabbit
9
-
10
- # Initializes now worker
11
- #
12
- # @param [String] exchange_name Name of the exchange queue is connected to.
13
- # @param [String] routing_key Routing key for binding queue to exchange
14
- # @param [String] queue_name Name of the queue worker is processing.
15
- # @param [Hash] options Worker options for RabbitMQ connection, retries and logger.
16
- #
17
- # @option options [String] :url AMQP connection url. Defaults to 'localhost'
18
- # @option options [Integer] :retry_limit Number of times message processing should be retried in case of an exception.
19
- # @option options [Integer] :retry_delay Delay between processing retries. Dafaults to 30 seconds. Cannot be changed without deleting or renameing a queue.
20
- # @option options [Logger] :logger Logger instance. Defaults to standard output.
21
- #
22
- # @api public
23
- def initialize(exchange_name, routing_key, queue_name, options = {})
24
- @queue_name = queue_name
25
- @amqp_url = options[:url] || "amqp://localhost:5672"
26
- @retry_limit = options[:retry_limit] || 8
27
- @retry_delay = (options[:retry_delay] || 30) * 1000 #ms
28
- @logger = options[:logger] || Logger.new(STDOUT)
29
-
30
- @rabbit = Tackle::Rabbit.new(exchange_name,
31
- routing_key,
32
- @queue_name,
33
- @amqp_url,
34
- @retry_delay,
35
- @logger)
36
-
37
- @rabbit.connect
38
- @rabbit.on_uncaught_exception(options[:on_uncaught_exception]) if options[:on_uncaught_exception]
39
- end
40
-
41
- # Subscribes for message deliveries
42
- #
43
- # @param [Block] Accepts a block that accepts message
44
- #
45
- # @api public
46
- def subscribe(&block)
47
- tackle_log("Subscribing to queue '#{@queue_name}'...")
48
- rabbit.queue.subscribe(:manual_ack => true,
49
- :block => true) do |delivery_info, properties, payload|
50
-
51
- tackle_log("Received message. Processing...")
52
- process_message(delivery_info, properties, payload, block)
53
- tackle_log("Done with processing message.")
54
-
55
- end
56
- rescue Interrupt => _
57
- rabbit.close
58
- rescue StandardError => ex
59
- tackle_log("An exception occured message='#{ex.message}'")
60
-
61
- raise ex
62
- end
63
-
64
- def process_message(delivery_info, properties, payload, block)
65
- begin
66
- tackle_log("Calling message processor...")
67
- block.call(payload)
68
- @rabbit.channel.ack(delivery_info.delivery_tag)
69
- tackle_log("Successfully processed message")
70
- rescue Exception => ex
71
- tackle_log("Failed to process message. Received exception '#{ex}'")
72
- try_again = Tackle::DelayedRetry.new(@rabbit.dead_letter_queue,
73
- properties,
74
- payload,
75
- @retry_limit,
76
- @logger)
77
- try_again.schedule_retry
78
- tackle_log("Sending negative acknowledgement to source queue...")
79
- @rabbit.channel.nack(delivery_info.delivery_tag)
80
- tackle_log("Negative acknowledgement sent")
81
-
82
- raise ex
83
- end
84
- end
85
- end
86
- end