active_publisher 0.4.0.pre1-java → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5cff30c85dcba8fd2b09a4b1585c6da7a4031313
4
- data.tar.gz: 7bc9d9c9a575a483e9ed3356d16a4c3ab5d6ed34
3
+ metadata.gz: 5af4607ffab1b83be825a72a22726e442ed1c3d5
4
+ data.tar.gz: 91c291269e965f25e2123177e6271f2fb7b13d92
5
5
  SHA512:
6
- metadata.gz: a9f9242c0321f8dda565ce2921bc0eb7116a95a22faba6064a026b9737c471f09699912c9aa3696f964731f53ab029277c2b0e02c831ffe2798564ce8b0e0c6a
7
- data.tar.gz: 488fb34a4eebf61759233601cb6cd8c0646362b720d0c126a958f2147e9ad00a4aca451f0784703d727604def1f29f0e923a7829f63cf1df07058fc9f955e5f2
6
+ metadata.gz: b5664f916eb23f5bd21aa9eaa58473639ace753bddf92d3f1441e5ae8e41dc98b6307bb442baa827ef2e1dc38e009133177c123151623ece55faf8e7c70d01a6
7
+ data.tar.gz: 7fa2ba9612e32d4c2cc021ba419000ed4fe3c7ef9c43ffca73fbd78430b960a530b2f6c7d4dd38e52fee8a6f4a0ba9b5c1cbe909235d644c6973e83c1ec99cfe
data/.travis.yml CHANGED
@@ -1,9 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2
4
3
  - 2.3
5
4
  - 2.4
6
- - jruby-1.7
7
5
  - jruby-9.1.12.0
8
6
  services:
9
7
  - rabbitmq
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_dependency 'bunny', '~> 2.1'
27
27
  end
28
28
 
29
+ spec.add_dependency 'activesupport', '>= 3.2'
29
30
  spec.add_dependency 'multi_op_queue', '>= 0.1.2'
30
31
 
31
32
  spec.add_development_dependency "bundler"
@@ -2,30 +2,48 @@ module ActivePublisher
2
2
  module Async
3
3
  module InMemoryAdapter
4
4
  class AsyncQueue
5
+ # These strategies are used to determine what to do with messages when the queue is full.
6
+ # :raise - Raise an error and drop the message.
7
+ # :drop - Silently drop the message.
8
+ # :wait - Wait for space in the queue to become available.
9
+ BACK_PRESSURE_STRATEGIES = [:raise, :drop, :wait].freeze
10
+
5
11
  include ::ActivePublisher::Logging
6
12
 
7
- attr_accessor :drop_messages_when_queue_full,
13
+ attr_accessor :back_pressure_strategy,
8
14
  :max_queue_size,
9
15
  :supervisor_interval
10
16
 
11
17
  attr_reader :consumer, :queue, :supervisor
12
18
 
13
- def initialize(drop_messages_when_queue_full, max_queue_size, supervisor_interval)
14
- @drop_messages_when_queue_full = drop_messages_when_queue_full
19
+ def initialize(back_pressure_strategy, max_queue_size, supervisor_interval)
20
+ self.back_pressure_strategy = back_pressure_strategy
15
21
  @max_queue_size = max_queue_size
16
22
  @supervisor_interval = supervisor_interval
17
23
  @queue = ::MultiOpQueue::Queue.new
18
24
  create_and_supervise_consumer!
19
25
  end
20
26
 
21
- def push(message)
22
- # default of 1_000_000 messages
23
- if queue.size > max_queue_size
24
- # Drop messages if the queue is full and we were configured to do so
25
- return if drop_messages_when_queue_full
27
+ def back_pressure_strategy=(strategy)
28
+ fail ::ArgumentError, "Invalid back pressure strategy: #{strategy}" unless BACK_PRESSURE_STRATEGIES.include?(strategy)
29
+ @back_pressure_strategy = strategy
30
+ end
26
31
 
27
- # By default we will raise an error to push the responsibility onto the caller
28
- fail ::ActivePublisher::Async::InMemoryAdapter::UnableToPersistMessageError, "Queue is full, messages will be dropped."
32
+ def push(message)
33
+ if queue.size >= max_queue_size
34
+ case back_pressure_strategy
35
+ when :drop
36
+ ::ActiveSupport::Notifications.instrument "message_dropped.active_publisher"
37
+ return
38
+ when :raise
39
+ ::ActiveSupport::Notifications.instrument "message_dropped.active_publisher"
40
+ fail ::ActivePublisher::Async::InMemoryAdapter::UnableToPersistMessageError, "Queue is full, messages will be dropped."
41
+ when :wait
42
+ ::ActiveSupport::Notifications.instrument "wait_for_async_queue.active_publisher" do
43
+ # This is a really crappy way to wait
44
+ sleep 0.01 until queue.size < max_queue_size
45
+ end
46
+ end
29
47
  end
30
48
 
31
49
  queue.push(message)
@@ -49,6 +67,9 @@ module ActivePublisher
49
67
  @consumer = ::ActivePublisher::Async::InMemoryAdapter::ConsumerThread.new(queue)
50
68
  end
51
69
 
70
+ # Notify the current queue size.
71
+ ::ActiveSupport::Notifications.instrument "async_queue_size.active_publisher", queue.size
72
+
52
73
  # Pause before checking the consumer again.
53
74
  sleep supervisor_interval
54
75
  end
@@ -86,25 +86,27 @@ module ActivePublisher
86
86
  end
87
87
 
88
88
  def publish_all(channel, exchange_name, messages)
89
- exchange = channel.topic(exchange_name)
90
- potentially_retry = []
91
- loop do
92
- break if messages.empty?
93
- message = messages.shift
94
-
95
- fail ActivePublisher::UnknownMessageClassError, "bulk publish messages must be ActivePublisher::Message" unless message.is_a?(ActivePublisher::Message)
96
- fail ActivePublisher::ExchangeMismatchError, "bulk publish messages must match publish_all exchange_name" if message.exchange_name != exchange_name
97
-
98
- begin
99
- options = ::ActivePublisher.publishing_options(message.route, message.options || {})
100
- exchange.publish(message.payload, options)
101
- potentially_retry << message
102
- rescue
103
- messages << message
104
- raise
89
+ ::ActiveSupport::Notifications.instrument "message_published.active_publisher", :message_count => messages.size do
90
+ exchange = channel.topic(exchange_name)
91
+ potentially_retry = []
92
+ loop do
93
+ break if messages.empty?
94
+ message = messages.shift
95
+
96
+ fail ActivePublisher::UnknownMessageClassError, "bulk publish messages must be ActivePublisher::Message" unless message.is_a?(ActivePublisher::Message)
97
+ fail ActivePublisher::ExchangeMismatchError, "bulk publish messages must match publish_all exchange_name" if message.exchange_name != exchange_name
98
+
99
+ begin
100
+ options = ::ActivePublisher.publishing_options(message.route, message.options || {})
101
+ exchange.publish(message.payload, options)
102
+ potentially_retry << message
103
+ rescue
104
+ messages << message
105
+ raise
106
+ end
105
107
  end
108
+ wait_for_confirms(channel, messages, potentially_retry)
106
109
  end
107
- wait_for_confirms(channel, messages, potentially_retry)
108
110
  end
109
111
 
110
112
  def wait_for_confirms(channel, messages, potentially_retry)
@@ -18,11 +18,11 @@ module ActivePublisher
18
18
 
19
19
  attr_reader :async_queue
20
20
 
21
- def initialize(drop_messages_when_queue_full = false, max_queue_size = 1_000_000, supervisor_interval = 0.2)
21
+ def initialize(back_pressure_strategy = :raise, max_queue_size = 100_000, supervisor_interval = 0.2)
22
22
  logger.info "Starting in-memory publisher adapter"
23
23
 
24
24
  @async_queue = ::ActivePublisher::Async::InMemoryAdapter::AsyncQueue.new(
25
- drop_messages_when_queue_full,
25
+ back_pressure_strategy,
26
26
  max_queue_size,
27
27
  supervisor_interval
28
28
  )
@@ -1,3 +1,3 @@
1
1
  module ActivePublisher
2
- VERSION = "0.4.0.pre1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -3,6 +3,7 @@ if ::RUBY_PLATFORM == "java"
3
3
  else
4
4
  require "bunny"
5
5
  end
6
+ require "active_support"
6
7
  require "thread"
7
8
 
8
9
  require "active_publisher/logging"
@@ -34,7 +35,9 @@ module ActivePublisher
34
35
  # @param [Hash] options hash to set message parameters (e.g. headers)
35
36
  def self.publish(route, payload, exchange_name, options = {})
36
37
  with_exchange(exchange_name) do |exchange|
37
- exchange.publish(payload, publishing_options(route, options))
38
+ ::ActiveSupport::Notifications.instrument "message_published.active_publisher" do
39
+ exchange.publish(payload, publishing_options(route, options))
40
+ end
38
41
  end
39
42
  end
40
43
 
@@ -48,7 +51,9 @@ module ActivePublisher
48
51
  fail ActivePublisher::ExchangeMismatchError, "bulk publish messages must match publish_all exchange_name" if message.exchange_name != exchange_name
49
52
 
50
53
  begin
51
- exchange.publish(message.payload, publishing_options(message.route, message.options || {}))
54
+ ::ActiveSupport::Notifications.instrument "message_published.active_publisher" do
55
+ exchange.publish(message.payload, publishing_options(message.route, message.options || {}))
56
+ end
52
57
  rescue
53
58
  messages << message
54
59
  raise
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: 0.4.0.pre1
4
+ version: 1.0.0
5
5
  platform: java
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: 2017-06-23 00:00:00.000000000 Z
15
+ date: 2017-09-07 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  requirement: !ruby/object:Gem::Requirement
@@ -28,6 +28,20 @@ dependencies:
28
28
  - - "~>"
29
29
  - !ruby/object:Gem::Version
30
30
  version: '2.7'
31
+ - !ruby/object:Gem::Dependency
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '3.2'
37
+ name: activesupport
38
+ prerelease: false
39
+ type: :runtime
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '3.2'
31
45
  - !ruby/object:Gem::Dependency
32
46
  requirement: !ruby/object:Gem::Requirement
33
47
  requirements:
@@ -145,13 +159,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
145
159
  version: '0'
146
160
  required_rubygems_version: !ruby/object:Gem::Requirement
147
161
  requirements:
148
- - - ">"
162
+ - - ">="
149
163
  - !ruby/object:Gem::Version
150
- version: 1.3.1
164
+ version: '0'
151
165
  requirements: []
152
166
  rubyforge_project:
153
- rubygems_version: 2.6.12
167
+ rubygems_version: 2.6.13
154
168
  signing_key:
155
169
  specification_version: 4
156
- summary: Aims to make publishing work across MRI and jRuby painless and add some nice features like automatially publishing lifecycle events for ActiveRecord models.
170
+ summary: Aims to make publishing work across MRI and jRuby painless and add some nice
171
+ features like automatially publishing lifecycle events for ActiveRecord models.
157
172
  test_files: []