eventboss 1.3.2 → 1.5.0

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: eaa1906368e8751476a4df0ae1f274a8008735de72191a34867881b50b19492b
4
- data.tar.gz: 20bfe9695bc682e801b5b6760b92b9d575d0f323218b4286196aaff6f702d30f
3
+ metadata.gz: 7d59c3796789baa9e13a8a2079b026909b2d37f426edeeed8936b83a1dfe97df
4
+ data.tar.gz: 2af186a964a87844ec33a5a625c21b847fe1c7782583bf760c30aa6037de592c
5
5
  SHA512:
6
- metadata.gz: a1e03452ce05f49cd5cbc09875467145d41c9fe8e6239941f874394a9895c617a2a2843daa479833a498d8ccbed6e6ac64b85ca3dab8dc73f42e2f980ba99468
7
- data.tar.gz: 6c8b23c2ace8d611e3a79f98dcf15a11a97dbba537a46ee97df970730ad0107eef117547697cdebbd2e4ab97404dd99dff388f6ccbfbccfcd9b5fdad9b68d5ae
6
+ metadata.gz: 8ff2e6aeaeb07d80a8e27a7609071a557ee2db659afa109035bbc7495f143e9bf9e504a48ac0358326583bab6ec1f670c241a2b35649c90b7adc2497396f7533
7
+ data.tar.gz: 514290d9f45c66124c433a33dd4f169719bec4d1a6141e1fe734c228e4363068199ab48962820cedbaff9299d30abeda497b3f31270ce4669bb2958b39e312b2
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [1.4.0] - 2020-04-18
8
+
9
+ - Introduce server middlewares (#31)
10
+
7
11
  ## [1.1.0] - 2019-07-16
8
12
 
9
13
  ### Added
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- eventboss (1.3.2)
4
+ eventboss (1.5.0)
5
5
  aws-sdk-sns (>= 1.1.0)
6
6
  aws-sdk-sqs (>= 1.3.0)
7
7
  dotenv (~> 2.1, >= 2.1.1)
@@ -9,25 +9,25 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- aws-eventstream (1.0.3)
13
- aws-partitions (1.269.0)
14
- aws-sdk-core (3.89.1)
15
- aws-eventstream (~> 1.0, >= 1.0.2)
12
+ aws-eventstream (1.1.0)
13
+ aws-partitions (1.374.0)
14
+ aws-sdk-core (3.107.0)
15
+ aws-eventstream (~> 1, >= 1.0.2)
16
16
  aws-partitions (~> 1, >= 1.239.0)
17
17
  aws-sigv4 (~> 1.1)
18
18
  jmespath (~> 1.0)
19
- aws-sdk-sns (1.21.0)
20
- aws-sdk-core (~> 3, >= 3.71.0)
19
+ aws-sdk-sns (1.28.0)
20
+ aws-sdk-core (~> 3, >= 3.99.0)
21
21
  aws-sigv4 (~> 1.1)
22
- aws-sdk-sqs (1.23.1)
23
- aws-sdk-core (~> 3, >= 3.71.0)
22
+ aws-sdk-sqs (1.33.0)
23
+ aws-sdk-core (~> 3, >= 3.99.0)
24
24
  aws-sigv4 (~> 1.1)
25
- aws-sigv4 (1.1.0)
26
- aws-eventstream (~> 1.0, >= 1.0.2)
25
+ aws-sigv4 (1.2.2)
26
+ aws-eventstream (~> 1, >= 1.0.2)
27
27
  diff-lcs (1.3)
28
- dotenv (2.7.5)
28
+ dotenv (2.7.6)
29
29
  jmespath (1.4.0)
30
- rake (12.3.1)
30
+ rake (13.0.1)
31
31
  rspec (3.7.0)
32
32
  rspec-core (~> 3.7.0)
33
33
  rspec-expectations (~> 3.7.0)
data/README.md CHANGED
@@ -151,20 +151,52 @@ Eventboss.configure do |config|
151
151
  end
152
152
  ```
153
153
 
154
- ## Development mode
154
+ ### Middlewares
155
+
156
+ Server middlewares intercept the execution of your `Listeners`. You can use to extract and run common functions on every message received.
157
+
158
+ Define a middleware in the following way:
159
+
160
+ ```ruby
161
+ class LogMiddleware < Eventboss::Middleware::Base
162
+ def call(_work)
163
+ yield
164
+ logger.debug 'finished with success'
165
+ rescue StandardError => _error
166
+ logger.error 'finished with error'
167
+ raise
168
+ end
169
+
170
+ private
171
+
172
+ def logger
173
+ @logger ||= @options.fetch(:logger)
174
+ end
175
+ end
176
+ ```
177
+
178
+ And configure your logger as such:
179
+
180
+ ```ruby
181
+ Eventboss.configure do |config|
182
+ config.server_middleware.add LogMiddleware, logger: Logger.new
183
+ end
184
+ ```
185
+
186
+ ## Development mode
155
187
 
156
188
  In the _development mode_ you don't need to create the infrastructure required by the application - Eventboss will take care of this.
157
189
 
158
190
  It works on AWS and [localstack](https://github.com/localstack/localstack).
159
191
 
160
- Following resources are created:
192
+ Following resources are created:
161
193
  * SNS topics - created when application starts and when message is published
162
194
  * SQS queues (with SendMessage policy) - created when application starts
163
195
  * subscriptions for topics and queues - created when application starts
164
196
 
165
197
  Just enable it via environment variable...
166
198
  ```
167
- EVENTBUS_DEVELOPMENT_MODE=true
199
+ EVENTBOSS_DEVELOPMENT_MODE=true
168
200
  ```
169
201
  use fixed account ID for localstack setup...
170
202
  ```
@@ -206,4 +238,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/AirHel
206
238
  ## License
207
239
 
208
240
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
209
-
@@ -13,6 +13,7 @@ require 'eventboss/logging'
13
13
  require 'eventboss/safe_thread'
14
14
  require 'eventboss/launcher'
15
15
  require 'eventboss/long_poller'
16
+ require 'eventboss/middleware'
16
17
  require 'eventboss/unit_of_work'
17
18
  require 'eventboss/worker'
18
19
  require 'eventboss/fetcher'
@@ -34,6 +34,7 @@ module Eventboss
34
34
  defined_or_default('error_handlers') do
35
35
  [ErrorHandlers::Logger.new].tap do |handlers|
36
36
  handlers << ErrorHandlers::DbConnectionDropHandler.new if defined?(::ActiveRecord::StatementInvalid)
37
+ handlers << ErrorHandlers::DbConnectionNotEstablishedHandler.new if defined?(::ActiveRecord::ConnectionNotEstablished)
37
38
  end
38
39
  end
39
40
  end
@@ -118,6 +119,10 @@ module Eventboss
118
119
  end
119
120
  end
120
121
 
122
+ def server_middleware
123
+ @server_middleware ||= Middleware::Chain.new
124
+ end
125
+
121
126
  private
122
127
 
123
128
  def defined_or_default(variable_name)
@@ -0,0 +1,11 @@
1
+ module Eventboss
2
+ module ErrorHandlers
3
+ class DbConnectionNotEstablishedHandler
4
+ def call(exception, _context = {})
5
+ if exception.class == ::ActiveRecord::ConnectionNotEstablished
6
+ ::ActiveRecord::Base.connection.reconnect!
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Eventboss
2
+ module ErrorHandlers
3
+ class Rollbar
4
+ def call(exception, context = {})
5
+ eventboss_context = { component: 'eventboss' }
6
+ eventboss_context[:action] = context[:processor].class.to_s if context[:processor]
7
+ ::Rollbar.error(exception, eventboss_context.merge(context))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,5 @@
1
1
  require 'eventboss/error_handlers/logger'
2
2
  require 'eventboss/error_handlers/airbrake'
3
+ require 'eventboss/error_handlers/rollbar'
3
4
  require 'eventboss/error_handlers/db_connection_drop_handler'
5
+ require 'eventboss/error_handlers/db_connection_not_established_handler'
@@ -0,0 +1,57 @@
1
+ module Eventboss
2
+ module Middleware
3
+ class Chain
4
+ attr_reader :entries
5
+
6
+ def initialize
7
+ @entries = []
8
+ end
9
+
10
+ def add(klass, options = {})
11
+ @entries << Entry.new(klass, options)
12
+ end
13
+
14
+ def invoke(*args)
15
+ chain = @entries.map(&:build).reverse!
16
+
17
+ invoke_lambda = lambda do
18
+ if (mid = chain.pop)
19
+ mid.call(*args, &invoke_lambda)
20
+ else
21
+ yield
22
+ end
23
+ end
24
+ invoke_lambda.call
25
+ end
26
+
27
+ def clear
28
+ @entries.clear
29
+ end
30
+ end
31
+
32
+ class Base
33
+ attr_reader :options
34
+
35
+ def initialize(options)
36
+ @options = options
37
+ end
38
+
39
+ def call
40
+ raise 'Not implemented'
41
+ end
42
+ end
43
+
44
+ class Entry
45
+ attr_reader :klass, :options
46
+
47
+ def initialize(klass, options)
48
+ @klass = klass
49
+ @options = options
50
+ end
51
+
52
+ def build
53
+ @klass.new(options)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -2,8 +2,9 @@ class Eventboss::Railtie < Rails::Railtie
2
2
  rake_tasks do
3
3
  load 'tasks/eventboss.rake'
4
4
 
5
- # Load rails environment before executing reload.
5
+ # Load rails environment before executing reload and purge.
6
6
  # It makes sure to load configuration file.
7
7
  task 'eventboss:deadletter:reload': :environment
8
+ task 'eventboss:deadletter:purge': :environment
8
9
  end
9
10
  end
@@ -1,3 +1,3 @@
1
1
  module Eventboss
2
- VERSION = "1.3.2"
2
+ VERSION = "1.5.0"
3
3
  end
@@ -20,7 +20,7 @@ module Eventboss
20
20
 
21
21
  def run
22
22
  while (work = @bus.pop)
23
- work.run
23
+ run_work(work)
24
24
  end
25
25
  @launcher.worker_stopped(self)
26
26
  rescue Eventboss::Shutdown
@@ -32,6 +32,12 @@ module Eventboss
32
32
  @launcher.worker_stopped(self, restart: true)
33
33
  end
34
34
 
35
+ def run_work(work)
36
+ server_middleware.invoke(work) do
37
+ work.run
38
+ end
39
+ end
40
+
35
41
  def terminate(wait = false)
36
42
  stop_token
37
43
  return unless @thread
@@ -51,5 +57,9 @@ module Eventboss
51
57
  def stop_token
52
58
  @bus << nil
53
59
  end
60
+
61
+ def server_middleware
62
+ Eventboss.configuration.server_middleware
63
+ end
54
64
  end
55
65
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= event_name.camelize %>Listener
4
+ include Eventboss::Listener
5
+
6
+ eventboss_options event_name: '<%= event_name %>'<%= source_app ? ", source_app: '#{ source_app }'" : "" %>
7
+
8
+ def receive(payload)
9
+ Rails.logger.tagged(jid) { Rails.logger.info("payload: #{ payload }") }
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Creates the Eventboss listener scaffold
4
+ #
5
+ # @example Invocation from terminal
6
+ # rails generate eventboss:listener get_well air-helper
7
+ #
8
+ module Eventboss
9
+ class ListenerGenerator < Rails::Generators::Base
10
+ source_root File.expand_path(__dir__)
11
+
12
+ argument :event_name, required: true
13
+ argument :source_app, required: false
14
+
15
+ desc 'Creates the Eventboss listener scaffold'
16
+ def create_listener_scaffold
17
+ template 'eventboss_listener.rb.erb', "app/listeners/#{ event_name }_listener.rb"
18
+ end
19
+ end
20
+ end
@@ -7,7 +7,7 @@ namespace :eventboss do
7
7
  source_app = args[:source_app]
8
8
  event_name = args[:event_name]
9
9
 
10
- # Zero means, fetch all messages
10
+ # Zero means: fetch all messages
11
11
  max_messages = args[:max_messages].to_i
12
12
 
13
13
  # Ensure we don't fetch more than 10 messages from SQS
@@ -15,13 +15,8 @@ namespace :eventboss do
15
15
 
16
16
  abort "[#{task.name}] At least event name should be passed as argument" unless event_name
17
17
 
18
- queue_name = [
19
- Eventboss.configuration.eventboss_app_name,
20
- Eventboss.configuration.sns_sqs_name_infix,
21
- source_app,
22
- event_name,
23
- Eventboss.env
24
- ].compact.join('-')
18
+ queue_name = compose_queue_name(source_app, event_name)
19
+
25
20
  puts "[#{task.name}] Reloading #{queue_name}-deadletter (max: #{ max_messages }, batch: #{ batch_size })"
26
21
  queue = Eventboss::Queue.new("#{queue_name}-deadletter")
27
22
  send_queue = Eventboss::Queue.new(queue_name)
@@ -38,7 +33,6 @@ namespace :eventboss do
38
33
  break if messages.count.zero?
39
34
 
40
35
  messages.each do |message|
41
- puts "[#{task.name}] Publishing message: #{message.body}"
42
36
  client.send_message(queue_url: send_queue.url, message_body: message.body)
43
37
  fetcher.delete(queue, message)
44
38
 
@@ -49,5 +43,51 @@ namespace :eventboss do
49
43
  break if max_messages > 0 && total >= max_messages
50
44
  end
51
45
  end
46
+
47
+ desc 'Purge deadletter queue'
48
+ task :purge, [:event_name, :source_app, :max_messages] do |task, args|
49
+ source_app = args[:source_app]
50
+ event_name = args[:event_name]
51
+
52
+ # Zero means: fetch all messages
53
+ max_messages = args[:max_messages].to_i
54
+
55
+ # Ensure we don't fetch more than 10 messages from SQS
56
+ batch_size = max_messages == 0 ? 10 : [10, max_messages].min
57
+
58
+ abort "[#{task.name}] At least event name should be passed as argument" unless event_name
59
+
60
+ queue_name = compose_queue_name(source_app, event_name)
61
+
62
+ puts "[#{task.name}] Purging #{queue_name}-deadletter (max: #{ max_messages }, batch: #{ batch_size })"
63
+ queue = Eventboss::Queue.new("#{queue_name}-deadletter")
64
+ puts "[#{task.name}] #{queue.url}"
65
+
66
+ fetcher = Eventboss::Fetcher.new(Eventboss.configuration)
67
+ total = 0
68
+ loop do
69
+ messages = fetcher.fetch(queue, batch_size)
70
+ break if messages.count.zero?
71
+
72
+ messages.each do |message|
73
+ fetcher.delete(queue, message)
74
+
75
+ total += 1
76
+ break if max_messages > 0 && total >= max_messages
77
+ end
78
+
79
+ break if max_messages > 0 && total >= max_messages
80
+ end
81
+ end
82
+
83
+ def compose_queue_name(source_app, event_name)
84
+ [
85
+ Eventboss.configuration.eventboss_app_name,
86
+ Eventboss.configuration.sns_sqs_name_infix,
87
+ source_app,
88
+ event_name,
89
+ Eventboss.env
90
+ ].compact.join('-')
91
+ end
52
92
  end
53
93
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eventboss
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - AirHelp
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-03 00:00:00.000000000 Z
11
+ date: 2021-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-sqs
@@ -126,7 +126,9 @@ files:
126
126
  - lib/eventboss/development_mode.rb
127
127
  - lib/eventboss/error_handlers/airbrake.rb
128
128
  - lib/eventboss/error_handlers/db_connection_drop_handler.rb
129
+ - lib/eventboss/error_handlers/db_connection_not_established_handler.rb
129
130
  - lib/eventboss/error_handlers/logger.rb
131
+ - lib/eventboss/error_handlers/rollbar.rb
130
132
  - lib/eventboss/extensions.rb
131
133
  - lib/eventboss/fetcher.rb
132
134
  - lib/eventboss/instrumentation.rb
@@ -134,6 +136,7 @@ files:
134
136
  - lib/eventboss/listener.rb
135
137
  - lib/eventboss/logging.rb
136
138
  - lib/eventboss/long_poller.rb
139
+ - lib/eventboss/middleware.rb
137
140
  - lib/eventboss/publisher.rb
138
141
  - lib/eventboss/queue.rb
139
142
  - lib/eventboss/queue_listener.rb
@@ -147,12 +150,14 @@ files:
147
150
  - lib/eventboss/unit_of_work.rb
148
151
  - lib/eventboss/version.rb
149
152
  - lib/eventboss/worker.rb
153
+ - lib/generators/eventboss/listener/eventboss_listener.rb.erb
154
+ - lib/generators/eventboss/listener/listener_generator.rb
150
155
  - lib/tasks/eventboss.rake
151
156
  homepage: https://github.com/AirHelp/eventboss
152
157
  licenses:
153
158
  - MIT
154
159
  metadata: {}
155
- post_install_message:
160
+ post_install_message:
156
161
  rdoc_options: []
157
162
  require_paths:
158
163
  - lib
@@ -167,8 +172,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
167
172
  - !ruby/object:Gem::Version
168
173
  version: '0'
169
174
  requirements: []
170
- rubygems_version: 3.0.3
171
- signing_key:
175
+ rubygems_version: 3.1.4
176
+ signing_key:
172
177
  specification_version: 4
173
178
  summary: Eventboss Ruby Client.
174
179
  test_files: []