eventboss 1.3.2 → 1.5.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +13 -13
- data/README.md +35 -4
- data/lib/eventboss.rb +1 -0
- data/lib/eventboss/configuration.rb +5 -0
- data/lib/eventboss/error_handlers/db_connection_not_established_handler.rb +11 -0
- data/lib/eventboss/error_handlers/rollbar.rb +11 -0
- data/lib/eventboss/extensions.rb +2 -0
- data/lib/eventboss/middleware.rb +57 -0
- data/lib/eventboss/railtie.rb +2 -1
- data/lib/eventboss/version.rb +1 -1
- data/lib/eventboss/worker.rb +11 -1
- data/lib/generators/eventboss/listener/eventboss_listener.rb.erb +11 -0
- data/lib/generators/eventboss/listener/listener_generator.rb +20 -0
- data/lib/tasks/eventboss.rake +49 -9
- metadata +11 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d59c3796789baa9e13a8a2079b026909b2d37f426edeeed8936b83a1dfe97df
|
4
|
+
data.tar.gz: 2af186a964a87844ec33a5a625c21b847fe1c7782583bf760c30aa6037de592c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ff2e6aeaeb07d80a8e27a7609071a557ee2db659afa109035bbc7495f143e9bf9e504a48ac0358326583bab6ec1f670c241a2b35649c90b7adc2497396f7533
|
7
|
+
data.tar.gz: 514290d9f45c66124c433a33dd4f169719bec4d1a6141e1fe734c228e4363068199ab48962820cedbaff9299d30abeda497b3f31270ce4669bb2958b39e312b2
|
data/CHANGELOG.md
CHANGED
@@ -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
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
eventboss (1.
|
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
|
13
|
-
aws-partitions (1.
|
14
|
-
aws-sdk-core (3.
|
15
|
-
aws-eventstream (~> 1
|
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.
|
20
|
-
aws-sdk-core (~> 3, >= 3.
|
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
|
-
aws-sdk-core (~> 3, >= 3.
|
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.
|
26
|
-
aws-eventstream (~> 1
|
25
|
+
aws-sigv4 (1.2.2)
|
26
|
+
aws-eventstream (~> 1, >= 1.0.2)
|
27
27
|
diff-lcs (1.3)
|
28
|
-
dotenv (2.7.
|
28
|
+
dotenv (2.7.6)
|
29
29
|
jmespath (1.4.0)
|
30
|
-
rake (
|
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
|
-
|
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
|
-
|
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
|
-
|
data/lib/eventboss.rb
CHANGED
@@ -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
|
data/lib/eventboss/extensions.rb
CHANGED
@@ -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
|
data/lib/eventboss/railtie.rb
CHANGED
@@ -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
|
data/lib/eventboss/version.rb
CHANGED
data/lib/eventboss/worker.rb
CHANGED
@@ -20,7 +20,7 @@ module Eventboss
|
|
20
20
|
|
21
21
|
def run
|
22
22
|
while (work = @bus.pop)
|
23
|
-
work
|
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
|
data/lib/tasks/eventboss.rake
CHANGED
@@ -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
|
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
|
-
|
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.
|
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:
|
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.
|
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: []
|