active_publisher 0.4.0.pre1-java → 1.0.0-java

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
  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: []