active_publisher 1.2.3 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d07df691c4875cf4b99d301fc9cc3113a83b8ecaf888b6d2b6320b887c74f2d
4
- data.tar.gz: 5b15565ea6e5d191bd251d527bf5f32377ec27e6642453b9fee3942538edca2e
3
+ metadata.gz: e544e43595bfa0c8fd2159358394239cee4524429e9ed78b53c54314c374c089
4
+ data.tar.gz: e9d5529b42236c24f415b544123ffed7dca080cff2d27877ee04a70e42fafee6
5
5
  SHA512:
6
- metadata.gz: 7517b881037d04cb66effd45d49e16b39adbbdd76dbc0568d49440e9fd6e0ba8c960c5abd0b0c8df38209efe3c40d751a92e4b469746e764ebf04c5be01de58d
7
- data.tar.gz: fd049283784c2a6eca92fdf7ab008364edf1c4e691b7a2f8adf2a724a4478576c91c5375633f6253fb16f9e7c84e379ff5b6fdb8d02caf4ff8227252d1168df2
6
+ metadata.gz: 00af8b7c41f06088f9dbd55b106884a74b3d76693c456b8532ed8fafbf5e2ea9861a0c624c8c1474dba4203122c3730736f7214ee58fab75a629ad977edfe843
7
+ data.tar.gz: 40849817585017241be4928abbae027e1e8a5ae968a91eec4f7994b1e61ed0dc7f966da7c480809760d5e4e457db4a017fabed609c5d801c153cd6cb6e37dda1
@@ -0,0 +1,56 @@
1
+ # Inspired by: http://mikebian.co/running-tests-against-multiple-ruby-versions-using-circleci/
2
+
3
+ version: 2.1
4
+
5
+ orbs:
6
+ ruby: circleci/ruby@1.1
7
+
8
+ jobs:
9
+ test:
10
+ parallelism: 1
11
+ parameters:
12
+ ruby-image:
13
+ type: string
14
+ docker:
15
+ - image: << parameters.ruby-image >>
16
+ - image: rabbitmq
17
+
18
+ steps:
19
+ - checkout
20
+ - run:
21
+ name: install dockerize
22
+ command: wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && sudo tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
23
+ environment:
24
+ DOCKERIZE_VERSION: v0.3.0
25
+ - run:
26
+ name: Wait for rabbitmq
27
+ command: dockerize -wait tcp://localhost:5672 -timeout 1m
28
+ - run:
29
+ name: Install bundler
30
+ command: gem install bundler
31
+ - run:
32
+ name: Which bundler?
33
+ command: bundle -v
34
+ - run:
35
+ name: bundle install
36
+ command: bundle install
37
+ - run:
38
+ name: rspec
39
+ command: bundle exec rspec
40
+
41
+ # strangely, there seems to be very little documentation about exactly how martix builds work.
42
+ # By defining a param inside your job definition, Circle CI will automatically spawn a job for
43
+ # unique param value passed via `matrix`. Neat!
44
+ # https://circleci.com/blog/circleci-matrix-jobs/
45
+ workflows:
46
+ build_and_test:
47
+ jobs:
48
+ - test:
49
+ matrix:
50
+ parameters:
51
+ ruby-image:
52
+ - circleci/ruby:2.5
53
+ - circleci/ruby:2.6
54
+ - circleci/ruby:2.7
55
+ - circleci/jruby:9.1
56
+ - circleci/jruby:9.2
@@ -2,7 +2,13 @@ module ActivePublisher
2
2
  module Async
3
3
  module InMemoryAdapter
4
4
  class ConsumerThread
5
- attr_reader :thread, :queue, :sampled_queue_size, :last_tick_at
5
+ attr_reader :channel, :thread, :queue, :sampled_queue_size, :last_tick_at
6
+
7
+ if ::RUBY_PLATFORM == "java"
8
+ CHANNEL_CLOSED_ERRORS = [::MarchHare::ChannelAlreadyClosed]
9
+ else
10
+ CHANNEL_CLOSED_ERRORS = [::Bunny::ChannelAlreadyClosed]
11
+ end
6
12
 
7
13
  if ::RUBY_PLATFORM == "java"
8
14
  NETWORK_ERRORS = [::MarchHare::NetworkException, ::MarchHare::ConnectionRefused,
@@ -45,6 +51,32 @@ module ActivePublisher
45
51
  end
46
52
  end
47
53
 
54
+ def cleanup_up_channel
55
+ return if @channel.nil?
56
+ @channel.close
57
+ rescue => error
58
+ ::ActivePublisher.configuration.error_handler.call(error, {:status => "Cleaning up the channel"})
59
+ end
60
+
61
+ def handle_current_messages_on_unknown_error(current_messages)
62
+ current_messages.each do |message|
63
+ # Degrade to single message publish ... or at least attempt to
64
+ begin
65
+ ::ActivePublisher.publish(message.route, message.payload, message.exchange_name, message.options)
66
+ current_messages.delete(message)
67
+ rescue *CHANNEL_CLOSED_ERRORS
68
+ # If the channel is bad, raise!
69
+ raise
70
+ rescue *PRECONDITION_ERRORS => error
71
+ # Delete messages if rabbitmq cannot declare the exchange (or somet other precondition failed).
72
+ ::ActivePublisher.configuration.error_handler.call(error, {:reason => "precondition failed", :message => message})
73
+ current_messages.delete(message)
74
+ rescue => other_error
75
+ ::ActivePublisher.configuration.error_handler.call(other_error, {:route => message.route, :payload => message.payload, :exchange_name => message.exchange_name, :options => message.options})
76
+ end
77
+ end
78
+ end
79
+
48
80
  def make_channel
49
81
  channel = ::ActivePublisher::Async::InMemoryAdapter::Channel.new
50
82
  channel.confirm_select if ::ActivePublisher.configuration.publisher_confirms
@@ -57,54 +89,50 @@ module ActivePublisher
57
89
 
58
90
  def start_thread
59
91
  return if alive?
60
- @thread = ::Thread.new do
61
- loop do
62
- # Sample the queue size so we don't shutdown when messages are in flight.
63
- @sampled_queue_size = queue.size
64
- current_messages = queue.pop_up_to(50, :timeout => 0.1)
65
- update_last_tick_at
66
- # If the queue is empty, we should continue to update to "last_tick_at" time.
67
- next if current_messages.nil?
68
-
69
- # We only look at active publisher messages. Everything else is dropped.
70
- current_messages.select! { |message| message.is_a?(::ActivePublisher::Message) }
71
-
72
- begin
73
- @channel ||= make_channel
74
-
75
- # Only open a single connection for each group of messages to an exchange
76
- current_messages.group_by(&:exchange_name).each do |exchange_name, messages|
77
- publish_all(@channel, exchange_name, messages)
78
- current_messages -= messages
79
- end
80
- rescue *NETWORK_ERRORS
81
- # Sleep because connection is down
82
- await_network_reconnect
83
- rescue => unknown_error
84
- ::ActivePublisher.configuration.error_handler.call(unknown_error, {:number_of_messages => current_messages.size})
85
- current_messages.each do |message|
86
- # Degrade to single message publish ... or at least attempt to
87
- begin
88
- ::ActivePublisher.publish(message.route, message.payload, message.exchange_name, message.options)
89
- current_messages.delete(message)
90
- rescue *PRECONDITION_ERRORS => error
91
- # Delete messages if rabbitmq cannot declare the exchange (or somet other precondition failed).
92
- ::ActivePublisher.configuration.error_handler.call(error, {:reason => "precondition failed", :message => message})
93
- current_messages.delete(message)
94
- rescue => individual_error
95
- ::ActivePublisher.configuration.error_handler.call(individual_error, {:route => message.route, :payload => message.payload, :exchange_name => message.exchange_name, :options => message.options})
96
- end
97
- end
98
-
99
- # TODO: Find a way to bubble this out of the thread for logging purposes.
100
- # Reraise the error out of the publisher loop. The Supervisor will restart the consumer.
101
- raise unknown_error
102
- ensure
103
- # Always requeue anything that gets stuck.
104
- queue.concat(current_messages) if current_messages && !current_messages.empty?
92
+ @channel = make_channel
93
+ @thread = ::Thread.new { start_consuming_thread }
94
+ end
95
+
96
+ def start_consuming_thread
97
+ loop do
98
+ # Sample the queue size so we don't shutdown when messages are in flight.
99
+ @sampled_queue_size = queue.size
100
+ current_messages = queue.pop_up_to(50, :timeout => 0.1)
101
+ update_last_tick_at
102
+ # If the queue is empty, we should continue to update to "last_tick_at" time.
103
+ next if current_messages.nil?
104
+
105
+ # We only look at active publisher messages. Everything else is dropped.
106
+ current_messages.select! { |message| message.is_a?(::ActivePublisher::Message) }
107
+
108
+ begin
109
+ # Only open a single connection for each group of messages to an exchange
110
+ current_messages.group_by(&:exchange_name).each do |exchange_name, messages|
111
+ publish_all(@channel, exchange_name, messages)
112
+ current_messages -= messages
105
113
  end
114
+ rescue *CHANNEL_CLOSED_ERRORS
115
+ # If the channel is bad, raise without sending one-by-one!
116
+ raise
117
+ rescue *NETWORK_ERRORS
118
+ # Sleep because connection is down
119
+ await_network_reconnect
120
+ rescue => unknown_error
121
+ ::ActivePublisher.configuration.error_handler.call(unknown_error, {:number_of_messages => current_messages.size})
122
+
123
+ # Attempt to deliver a message one-by-one. Raise if a closed channel error appears.
124
+ handle_current_messages_on_unknown_error(current_messages)
125
+
126
+ # TODO: Find a way to bubble this out of the thread for logging purposes.
127
+ # Reraise the error out of the publisher loop. The Supervisor will restart the consumer.
128
+ raise unknown_error
129
+ ensure
130
+ # Always requeue anything that gets stuck.
131
+ queue.concat(current_messages) if current_messages && !current_messages.empty?
106
132
  end
107
133
  end
134
+ ensure
135
+ cleanup_up_channel
108
136
  end
109
137
 
110
138
  def publish_all(channel, exchange_name, messages)
@@ -1,3 +1,3 @@
1
1
  module ActivePublisher
2
- VERSION = "1.2.3"
2
+ VERSION = "1.2.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Stien
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: exe
14
14
  cert_chain: []
15
- date: 2020-07-29 00:00:00.000000000 Z
15
+ date: 2020-11-20 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bunny
@@ -179,9 +179,9 @@ executables: []
179
179
  extensions: []
180
180
  extra_rdoc_files: []
181
181
  files:
182
+ - ".circleci/config.yml"
182
183
  - ".gitignore"
183
184
  - ".rspec"
184
- - ".travis.yml"
185
185
  - CODE_OF_CONDUCT.md
186
186
  - Gemfile
187
187
  - LICENSE.txt
@@ -1,14 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.3.8
4
- - 2.5.7
5
- - jruby-9.1.12.0
6
- - jruby-9.2.7.0
7
- addons:
8
- apt:
9
- packages:
10
- - rabbitmq-server
11
- services:
12
- - rabbitmq
13
- sudo: false
14
- cache: bundler