hanami-events-cloud_pubsub 2.9.0 → 3.0.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/.rubocop.yml +2 -1
- data/.rubocop_todo.yml +14 -10
- data/Gemfile.lock +21 -20
- data/examples/client.rb +1 -1
- data/examples/server.rb +2 -0
- data/hanami-events-cloud_pubsub.gemspec +4 -1
- data/lib/hanami/events/adapter/cloud_pubsub.rb +26 -11
- data/lib/hanami/events/cloud_pubsub.rb +10 -4
- data/lib/hanami/events/cloud_pubsub/cli.rb +2 -2
- data/lib/hanami/events/cloud_pubsub/listener.rb +35 -10
- data/lib/hanami/events/cloud_pubsub/middleware/stack.rb +3 -3
- data/lib/hanami/events/cloud_pubsub/runner.rb +4 -8
- data/lib/hanami/events/cloud_pubsub/thread_inspector.rb +1 -1
- data/lib/hanami/events/cloud_pubsub/version.rb +1 -1
- metadata +22 -9
- data/lib/hanami/events/cloud_pubsub/middleware/auto_retry.rb +0 -93
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd0a13431ee107060d1d5df6dac57392e421053f13e58dc9d7144bb01008be12
|
|
4
|
+
data.tar.gz: d71e132eee40d004bf01827de7b5782ae1ca77b909fd884288bb0fc84f6d9a30
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5740b2f509eca29b70870b32adf7508bdc776a9d2efea0c41540fef600d26464eed902752b8095d5e3f028a04a08d5b13f7bc4b8ad313d24c008b96973542a8e
|
|
7
|
+
data.tar.gz: e75c53c924ab42ca5db76d02217e2e2f82ce83f1ae6e63e85640cfab894380282bca5bad9deeabb64970d88d2788ceaf5aec09999af4d8e8342ec5eac46180fe
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on
|
|
3
|
+
# on 2020-09-25 19:54:44 UTC using RuboCop version 0.89.0.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
|
8
8
|
|
|
9
|
-
# Offense count:
|
|
10
|
-
#
|
|
9
|
+
# Offense count: 2
|
|
10
|
+
# Cop supports --auto-correct.
|
|
11
|
+
Lint/RedundantCopDisableDirective:
|
|
12
|
+
Exclude:
|
|
13
|
+
- 'lib/hanami/events/adapter/cloud_pubsub.rb'
|
|
14
|
+
|
|
15
|
+
# Offense count: 3
|
|
16
|
+
# Configuration parameters: IgnoredMethods.
|
|
17
|
+
Metrics/AbcSize:
|
|
18
|
+
Max: 21
|
|
19
|
+
|
|
20
|
+
# Offense count: 4
|
|
21
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
|
|
11
22
|
Metrics/MethodLength:
|
|
12
23
|
Max: 14
|
|
13
24
|
|
|
@@ -16,10 +27,3 @@ Metrics/MethodLength:
|
|
|
16
27
|
Style/GlobalVars:
|
|
17
28
|
Exclude:
|
|
18
29
|
- 'examples/server.rb'
|
|
19
|
-
|
|
20
|
-
# Offense count: 35
|
|
21
|
-
# Cop supports --auto-correct.
|
|
22
|
-
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
|
23
|
-
# URISchemes: http, https
|
|
24
|
-
Metrics/LineLength:
|
|
25
|
-
Max: 96
|
data/Gemfile.lock
CHANGED
|
@@ -8,9 +8,10 @@ GIT
|
|
|
8
8
|
PATH
|
|
9
9
|
remote: .
|
|
10
10
|
specs:
|
|
11
|
-
hanami-events-cloud_pubsub (
|
|
11
|
+
hanami-events-cloud_pubsub (3.0.0)
|
|
12
12
|
dry-configurable (>= 0.8)
|
|
13
|
-
|
|
13
|
+
gapic-common (>= 0.3.4)
|
|
14
|
+
google-cloud-pubsub (>= 0.38.1, < 2.1)
|
|
14
15
|
hanami-cli (~> 0.2)
|
|
15
16
|
hanami-events (~> 0.2.0)
|
|
16
17
|
rack
|
|
@@ -37,26 +38,27 @@ GEM
|
|
|
37
38
|
dry-equalizer (0.3.0)
|
|
38
39
|
faraday (1.0.1)
|
|
39
40
|
multipart-post (>= 1.2, < 3)
|
|
41
|
+
gapic-common (0.3.4)
|
|
42
|
+
google-protobuf (~> 3.12, >= 3.12.2)
|
|
43
|
+
googleapis-common-protos (>= 1.3.9, < 2.0)
|
|
44
|
+
googleapis-common-protos-types (>= 1.0.4, < 2.0)
|
|
45
|
+
googleauth (~> 0.9)
|
|
46
|
+
grpc (~> 1.25)
|
|
40
47
|
google-cloud-core (1.5.0)
|
|
41
48
|
google-cloud-env (~> 1.0)
|
|
42
49
|
google-cloud-errors (~> 1.0)
|
|
43
50
|
google-cloud-env (1.3.3)
|
|
44
51
|
faraday (>= 0.17.3, < 2.0)
|
|
45
52
|
google-cloud-errors (1.0.1)
|
|
46
|
-
google-cloud-pubsub (
|
|
53
|
+
google-cloud-pubsub (2.0.0)
|
|
47
54
|
concurrent-ruby (~> 1.1)
|
|
48
|
-
google-cloud-core (~> 1.
|
|
49
|
-
google-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
googleapis-common-protos (>= 1.3.9, < 2.0)
|
|
56
|
-
googleauth (~> 0.9)
|
|
57
|
-
grpc (~> 1.24)
|
|
58
|
-
rly (~> 0.2.3)
|
|
59
|
-
google-protobuf (3.12.4)
|
|
55
|
+
google-cloud-core (~> 1.5)
|
|
56
|
+
google-cloud-pubsub-v1 (~> 0.0)
|
|
57
|
+
google-cloud-pubsub-v1 (0.1.2)
|
|
58
|
+
gapic-common (~> 0.3)
|
|
59
|
+
google-cloud-errors (~> 1.0)
|
|
60
|
+
grpc-google-iam-v1 (>= 0.6.10, < 2.0)
|
|
61
|
+
google-protobuf (3.13.0)
|
|
60
62
|
googleapis-common-protos (1.3.10)
|
|
61
63
|
google-protobuf (~> 3.11)
|
|
62
64
|
googleapis-common-protos-types (>= 1.0.5, < 2.0)
|
|
@@ -70,8 +72,8 @@ GEM
|
|
|
70
72
|
multi_json (~> 1.11)
|
|
71
73
|
os (>= 0.9, < 2.0)
|
|
72
74
|
signet (~> 0.14)
|
|
73
|
-
grpc (1.
|
|
74
|
-
google-protobuf (~> 3.
|
|
75
|
+
grpc (1.32.0)
|
|
76
|
+
google-protobuf (~> 3.13)
|
|
75
77
|
googleapis-common-protos-types (~> 1.0)
|
|
76
78
|
grpc-google-iam-v1 (0.6.10)
|
|
77
79
|
google-protobuf (~> 3.11)
|
|
@@ -83,7 +85,7 @@ GEM
|
|
|
83
85
|
hanami-utils (1.3.6)
|
|
84
86
|
concurrent-ruby (~> 1.0)
|
|
85
87
|
transproc (~> 1.0)
|
|
86
|
-
jwt (2.2.
|
|
88
|
+
jwt (2.2.2)
|
|
87
89
|
memoist (0.16.2)
|
|
88
90
|
method_source (1.0.0)
|
|
89
91
|
multi_json (1.15.0)
|
|
@@ -96,14 +98,13 @@ GEM
|
|
|
96
98
|
pry (0.13.1)
|
|
97
99
|
coderay (~> 1.1)
|
|
98
100
|
method_source (~> 1.0)
|
|
99
|
-
public_suffix (4.0.
|
|
101
|
+
public_suffix (4.0.6)
|
|
100
102
|
rack (2.2.3)
|
|
101
103
|
rainbow (3.0.0)
|
|
102
104
|
rake (13.0.1)
|
|
103
105
|
regexp_parser (1.7.1)
|
|
104
106
|
request_id (0.4.3)
|
|
105
107
|
rexml (3.2.4)
|
|
106
|
-
rly (0.2.3)
|
|
107
108
|
rspec (3.9.0)
|
|
108
109
|
rspec-core (~> 3.9.0)
|
|
109
110
|
rspec-expectations (~> 3.9.0)
|
data/examples/client.rb
CHANGED
|
@@ -12,7 +12,7 @@ Hanami::Events::CloudPubsub.setup
|
|
|
12
12
|
|
|
13
13
|
pubsub = Google::Cloud::Pubsub.new project_id: 'emulator'
|
|
14
14
|
|
|
15
|
-
events = Hanami::Events.initialize(:cloud_pubsub, pubsub: pubsub, logger: Logger.new(
|
|
15
|
+
events = Hanami::Events.initialize(:cloud_pubsub, pubsub: pubsub, logger: Logger.new($stdout))
|
|
16
16
|
|
|
17
17
|
3.times do
|
|
18
18
|
events.broadcast('user.deleted', user_id: 1)
|
data/examples/server.rb
CHANGED
|
@@ -4,6 +4,8 @@ Hanami::Events::CloudPubsub.configure do |config|
|
|
|
4
4
|
config.subscriber.streams = 2
|
|
5
5
|
config.subscriber.threads.push = 2
|
|
6
6
|
config.subscriber.threads.callback = 2
|
|
7
|
+
config.auto_retry.enabled = true
|
|
8
|
+
config.auto_retry.dead_letter_topic_name = 'my-dead-letter-topic-name'
|
|
7
9
|
|
|
8
10
|
config.subscriptions_loader = -> do
|
|
9
11
|
$events.subscribe('user.deleted', id: 'testing-2') do |payload|
|
|
@@ -15,6 +15,8 @@ Gem::Specification.new do |spec|
|
|
|
15
15
|
spec.homepage = 'https://github.com/adHawk/hanami-events-cloud_pubsub'
|
|
16
16
|
spec.license = 'MIT'
|
|
17
17
|
|
|
18
|
+
spec.required_ruby_version = '>= 2.5.0'
|
|
19
|
+
|
|
18
20
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
19
21
|
f.match(%r{^(test|spec|features)/})
|
|
20
22
|
end
|
|
@@ -23,7 +25,8 @@ Gem::Specification.new do |spec|
|
|
|
23
25
|
spec.require_paths = ['lib']
|
|
24
26
|
|
|
25
27
|
spec.add_dependency 'dry-configurable', '>= 0.8'
|
|
26
|
-
spec.add_dependency '
|
|
28
|
+
spec.add_dependency 'gapic-common', '>= 0.3.4'
|
|
29
|
+
spec.add_dependency 'google-cloud-pubsub', '>= 0.38.1', '< 2.1'
|
|
27
30
|
spec.add_dependency 'hanami-cli', '~> 0.2'
|
|
28
31
|
spec.add_dependency 'hanami-events', '~> 0.2.0'
|
|
29
32
|
spec.add_dependency 'rack'
|
|
@@ -15,7 +15,7 @@ module Hanami
|
|
|
15
15
|
|
|
16
16
|
def initialize(params)
|
|
17
17
|
@pubsub = params[:pubsub]
|
|
18
|
-
@logger = params[:logger] || Logger.new(
|
|
18
|
+
@logger = params[:logger] || Logger.new($stdout)
|
|
19
19
|
@listen = params[:listen] || false
|
|
20
20
|
@subscribers = Concurrent::Array.new
|
|
21
21
|
@listeners = Concurrent::Array.new
|
|
@@ -29,15 +29,21 @@ module Hanami
|
|
|
29
29
|
#
|
|
30
30
|
# @param event [Symbol, String] the event name
|
|
31
31
|
# @param payload [Hash] the event data
|
|
32
|
-
def broadcast(name,
|
|
32
|
+
def broadcast(name, input_payload, **message_opts)
|
|
33
33
|
event_name = namespaced(name)
|
|
34
34
|
topic = topic_for event_name
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
middleware.invoke(
|
|
39
|
-
topic.publish_async(
|
|
40
|
-
|
|
35
|
+
serialized_payload = serializer.serialize(input_payload)
|
|
36
|
+
attrs = { id: SecureRandom.uuid, event_name: event_name }
|
|
37
|
+
|
|
38
|
+
middleware.invoke(serialized_payload, **attrs, **message_opts) do |payload, **opts|
|
|
39
|
+
topic.publish_async(payload, **opts) do |result|
|
|
40
|
+
msg = result.message.grpc.to_h
|
|
41
|
+
|
|
42
|
+
if result.succeeded?
|
|
43
|
+
logger.info "Published #{name.inspect} published", **msg
|
|
44
|
+
else
|
|
45
|
+
logger.warn "Failed to broadcast #{name.inspect} event", error: result.error, **msg # rubocop:disable Layout/LineLength
|
|
46
|
+
end
|
|
41
47
|
end
|
|
42
48
|
end
|
|
43
49
|
end
|
|
@@ -77,7 +83,8 @@ module Hanami
|
|
|
77
83
|
handler: method(:call_subscribers),
|
|
78
84
|
logger: logger,
|
|
79
85
|
topic: topic,
|
|
80
|
-
subscriber_opts: subscriber_opts
|
|
86
|
+
subscriber_opts: subscriber_opts,
|
|
87
|
+
dead_letter_topic: dead_letter_topic
|
|
81
88
|
)
|
|
82
89
|
|
|
83
90
|
@listeners << listener
|
|
@@ -98,7 +105,7 @@ module Hanami
|
|
|
98
105
|
@serializer ||= Hanami::Events::Serializer[@serializer_type].new
|
|
99
106
|
end
|
|
100
107
|
|
|
101
|
-
# rubocop:disable
|
|
108
|
+
# rubocop:disable Layout/LineLength
|
|
102
109
|
def topic_for(name)
|
|
103
110
|
return @topic_registry[name.to_s] if @topic_registry[name.to_s]
|
|
104
111
|
|
|
@@ -110,7 +117,15 @@ module Hanami
|
|
|
110
117
|
|
|
111
118
|
@topic_registry[name.to_s] = topic
|
|
112
119
|
end
|
|
113
|
-
# rubocop:enable
|
|
120
|
+
# rubocop:enable Layout/LineLength
|
|
121
|
+
|
|
122
|
+
def dead_letter_topic
|
|
123
|
+
conf = Hanami::Events::CloudPubsub.config.auto_retry
|
|
124
|
+
|
|
125
|
+
return unless conf.enabled
|
|
126
|
+
|
|
127
|
+
topic_for namespaced(conf.dead_letter_topic_name)
|
|
128
|
+
end
|
|
114
129
|
|
|
115
130
|
def namespaced(val, sep: '.')
|
|
116
131
|
[Hanami::Events::CloudPubsub.namespace, val].compact.join(sep)
|
|
@@ -5,7 +5,6 @@ require 'hanami/events'
|
|
|
5
5
|
require 'hanami/events/cloud_pubsub/version'
|
|
6
6
|
require 'hanami/events/cloud_pubsub/middleware/stack'
|
|
7
7
|
require 'hanami/events/cloud_pubsub/middleware/logging'
|
|
8
|
-
require 'hanami/events/cloud_pubsub/middleware/auto_retry'
|
|
9
8
|
require 'hanami/events/cloud_pubsub/runner'
|
|
10
9
|
require 'hanami/events/cloud_pubsub/errors'
|
|
11
10
|
require 'google/cloud/pubsub'
|
|
@@ -32,7 +31,7 @@ module Hanami
|
|
|
32
31
|
setting :project_id, reader: true
|
|
33
32
|
setting :auto_create_subscriptions, false, reader: true
|
|
34
33
|
setting :auto_create_topics, false, reader: true
|
|
35
|
-
setting :logger, Logger.new(
|
|
34
|
+
setting :logger, Logger.new($stdout), reader: true
|
|
36
35
|
setting :subscriptions_loader, proc {
|
|
37
36
|
abort <<~MSG
|
|
38
37
|
┌────────────────────────────────────────────────────────────────────────────────┐
|
|
@@ -58,8 +57,7 @@ module Hanami
|
|
|
58
57
|
], reader: true
|
|
59
58
|
|
|
60
59
|
middleware_stack = Middleware::Stack.new(
|
|
61
|
-
Middleware::Logging.new
|
|
62
|
-
Middleware::AutoRetry.new
|
|
60
|
+
Middleware::Logging.new
|
|
63
61
|
)
|
|
64
62
|
|
|
65
63
|
begin
|
|
@@ -89,6 +87,14 @@ module Hanami
|
|
|
89
87
|
|
|
90
88
|
setting :on_shutdown_handlers, [], reader: true
|
|
91
89
|
|
|
90
|
+
setting :auto_retry do
|
|
91
|
+
setting :enabled, false
|
|
92
|
+
setting :max_attempts, 1200
|
|
93
|
+
setting :dead_letter_topic_name
|
|
94
|
+
setting :minimum_backoff, 30
|
|
95
|
+
setting :maximum_backoff, 600
|
|
96
|
+
end
|
|
97
|
+
|
|
92
98
|
def self.finalize_settings!
|
|
93
99
|
conf_hash = config.pubsub
|
|
94
100
|
conf_hash.each { |key, val| Google::Cloud::Pubsub.configure[key] = val }
|
|
@@ -5,6 +5,7 @@ require 'hanami/events/cloud_pubsub/safe_error_handler'
|
|
|
5
5
|
module Hanami
|
|
6
6
|
module Events
|
|
7
7
|
module CloudPubsub
|
|
8
|
+
# rubocop:disable Metrics/ClassLength:
|
|
8
9
|
# @api private
|
|
9
10
|
class Listener
|
|
10
11
|
attr_reader :topic,
|
|
@@ -13,8 +14,10 @@ module Hanami
|
|
|
13
14
|
:logger,
|
|
14
15
|
:handler,
|
|
15
16
|
:event_name,
|
|
16
|
-
:
|
|
17
|
-
:middleware
|
|
17
|
+
:input_subscriber_opts,
|
|
18
|
+
:middleware,
|
|
19
|
+
:dead_letter_topic
|
|
20
|
+
|
|
18
21
|
# rubocop:disable Metrics/ParameterLists
|
|
19
22
|
def initialize(topic:,
|
|
20
23
|
logger:,
|
|
@@ -22,25 +25,24 @@ module Hanami
|
|
|
22
25
|
event_name:,
|
|
23
26
|
subscriber_id:,
|
|
24
27
|
subscriber_opts: {},
|
|
25
|
-
middleware: CloudPubsub.config.middleware
|
|
28
|
+
middleware: CloudPubsub.config.middleware,
|
|
29
|
+
dead_letter_topic: nil)
|
|
26
30
|
@topic = topic
|
|
27
31
|
@logger = logger
|
|
28
32
|
@handler = handler
|
|
29
33
|
@event_name = event_name
|
|
30
34
|
@subscriber_id = subscriber_id
|
|
31
|
-
@
|
|
35
|
+
@input_subscriber_opts = subscriber_opts
|
|
32
36
|
@middleware = middleware
|
|
37
|
+
@dead_letter_topic = dead_letter_topic
|
|
33
38
|
end
|
|
34
39
|
# rubocop:enable Metrics/ParameterLists
|
|
35
40
|
|
|
36
41
|
def register
|
|
37
42
|
subscription = subscription_for(subscriber_id)
|
|
38
|
-
|
|
39
|
-
listener = subscription.listen(**
|
|
40
|
-
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
logger.debug("Registered listener for #{subscriber_id} with opts #{subscriber_opts}")
|
|
43
|
+
apply_retry_options(subscription)
|
|
44
|
+
listener = subscription.listen(**subscriber_options) { |m| handle_message(m) }
|
|
45
|
+
logger.debug("Registered listener for #{subscriber_id} with: #{subscriber_options}")
|
|
44
46
|
|
|
45
47
|
@subscriber = listener
|
|
46
48
|
|
|
@@ -86,6 +88,8 @@ module Hanami
|
|
|
86
88
|
rescue StandardError => e
|
|
87
89
|
run_error_handlers(e, message)
|
|
88
90
|
raise
|
|
91
|
+
ensure
|
|
92
|
+
message.nack! if CloudPubsub.config.auto_retry.enabled
|
|
89
93
|
end
|
|
90
94
|
|
|
91
95
|
def subscription_for(name)
|
|
@@ -120,7 +124,28 @@ module Hanami
|
|
|
120
124
|
"a subscription already exists for #{sub_name} " \
|
|
121
125
|
"but its name #{found_subscription.topic.name} does not match #{@event_name}"
|
|
122
126
|
end
|
|
127
|
+
|
|
128
|
+
def subscriber_options
|
|
129
|
+
@subscriber_options ||= {
|
|
130
|
+
**CloudPubsub.config.subscriber.to_h,
|
|
131
|
+
**input_subscriber_opts
|
|
132
|
+
}
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def apply_retry_options(sub)
|
|
136
|
+
return {} unless CloudPubsub.config.auto_retry.enabled
|
|
137
|
+
|
|
138
|
+
sub.retry_policy = Google::Cloud::PubSub::RetryPolicy.new(
|
|
139
|
+
minimum_backoff: CloudPubsub.config.auto_retry.minimum_backoff,
|
|
140
|
+
maximum_backoff: CloudPubsub.config.auto_retry.maximum_backoff
|
|
141
|
+
)
|
|
142
|
+
sub.dead_letter_topic = dead_letter_topic
|
|
143
|
+
sub.dead_letter_max_delivery_attempts = CloudPubsub.config.auto_retry.max_attempts
|
|
144
|
+
|
|
145
|
+
sub
|
|
146
|
+
end
|
|
123
147
|
end
|
|
148
|
+
# rubocop:enable Metrics/ClassLength:
|
|
124
149
|
end
|
|
125
150
|
end
|
|
126
151
|
end
|
|
@@ -40,14 +40,14 @@ module Hanami
|
|
|
40
40
|
@entries.shift
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
def invoke(*args)
|
|
43
|
+
def invoke(*args, **kwargs)
|
|
44
44
|
stack = entries.dup
|
|
45
45
|
|
|
46
46
|
traverse_stack = proc do |**opts|
|
|
47
47
|
if stack.empty?
|
|
48
|
-
yield(*args)
|
|
48
|
+
yield(*args, **kwargs, **opts)
|
|
49
49
|
else
|
|
50
|
-
stack.shift.call(*args, **opts, &traverse_stack)
|
|
50
|
+
stack.shift.call(*args, **kwargs, **opts, &traverse_stack)
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -86,13 +86,12 @@ module Hanami
|
|
|
86
86
|
# some reason.
|
|
87
87
|
#
|
|
88
88
|
# See: https://github.com/mperham/sidekiq/blob/e447dae961ebc894f12848d9f33446a07ffc67dc/bin/sidekiqload#L74
|
|
89
|
-
# rubocop:disable Metrics/AbcSize
|
|
90
89
|
def debug_info
|
|
91
90
|
<<~MSG
|
|
92
91
|
╔══════ BACKTRACES
|
|
93
92
|
#{Thread.list.flat_map { |thr| ThreadInspector.new(thr).to_s }.join("\n")}
|
|
94
93
|
╠══════ LISTENERS
|
|
95
|
-
#{adapter.listeners.map { |lis|
|
|
94
|
+
#{adapter.listeners.map { |lis| "║ #{lis.format}" }.join("\n")}
|
|
96
95
|
║
|
|
97
96
|
╠══════ GENERAL
|
|
98
97
|
║ ready?: #{ready?}
|
|
@@ -102,7 +101,6 @@ module Hanami
|
|
|
102
101
|
╚══════
|
|
103
102
|
MSG
|
|
104
103
|
end
|
|
105
|
-
# rubocop:enable Metrics/AbcSize
|
|
106
104
|
|
|
107
105
|
def sleep_for_a_bit
|
|
108
106
|
sleep @sleep_time
|
|
@@ -114,11 +112,9 @@ module Hanami
|
|
|
114
112
|
logger.info('Calling custom on_shutdown handler')
|
|
115
113
|
|
|
116
114
|
CloudPubsub.on_shutdown_handlers.each do |handler|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
logger.warn("Shutdown handler failed (#{e.message})")
|
|
121
|
-
end
|
|
115
|
+
handler.call(adapter)
|
|
116
|
+
rescue StandardError => e
|
|
117
|
+
logger.warn("Shutdown handler failed (#{e.message})")
|
|
122
118
|
end
|
|
123
119
|
end
|
|
124
120
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hanami-events-cloud_pubsub
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ian Ker-Seymer
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-09-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: dry-configurable
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0.8'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: gapic-common
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 0.3.4
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 0.3.4
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: google-cloud-pubsub
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -33,7 +47,7 @@ dependencies:
|
|
|
33
47
|
version: 0.38.1
|
|
34
48
|
- - "<"
|
|
35
49
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: '1
|
|
50
|
+
version: '2.1'
|
|
37
51
|
type: :runtime
|
|
38
52
|
prerelease: false
|
|
39
53
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -43,7 +57,7 @@ dependencies:
|
|
|
43
57
|
version: 0.38.1
|
|
44
58
|
- - "<"
|
|
45
59
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '1
|
|
60
|
+
version: '2.1'
|
|
47
61
|
- !ruby/object:Gem::Dependency
|
|
48
62
|
name: hanami-cli
|
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -178,7 +192,6 @@ files:
|
|
|
178
192
|
- lib/hanami/events/cloud_pubsub/health_check_server.rb
|
|
179
193
|
- lib/hanami/events/cloud_pubsub/integration.rb
|
|
180
194
|
- lib/hanami/events/cloud_pubsub/listener.rb
|
|
181
|
-
- lib/hanami/events/cloud_pubsub/middleware/auto_retry.rb
|
|
182
195
|
- lib/hanami/events/cloud_pubsub/middleware/client/request_id.rb
|
|
183
196
|
- lib/hanami/events/cloud_pubsub/middleware/logging.rb
|
|
184
197
|
- lib/hanami/events/cloud_pubsub/middleware/prometheus.rb
|
|
@@ -195,7 +208,7 @@ homepage: https://github.com/adHawk/hanami-events-cloud_pubsub
|
|
|
195
208
|
licenses:
|
|
196
209
|
- MIT
|
|
197
210
|
metadata: {}
|
|
198
|
-
post_install_message:
|
|
211
|
+
post_install_message:
|
|
199
212
|
rdoc_options: []
|
|
200
213
|
require_paths:
|
|
201
214
|
- lib
|
|
@@ -203,7 +216,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
203
216
|
requirements:
|
|
204
217
|
- - ">="
|
|
205
218
|
- !ruby/object:Gem::Version
|
|
206
|
-
version:
|
|
219
|
+
version: 2.5.0
|
|
207
220
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
221
|
requirements:
|
|
209
222
|
- - ">="
|
|
@@ -211,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
211
224
|
version: '0'
|
|
212
225
|
requirements: []
|
|
213
226
|
rubygems_version: 3.1.2
|
|
214
|
-
signing_key:
|
|
227
|
+
signing_key:
|
|
215
228
|
specification_version: 4
|
|
216
229
|
summary: Google Cloud Pub/Sub adapter for the hanami-events gem
|
|
217
230
|
test_files: []
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Hanami
|
|
4
|
-
module Events
|
|
5
|
-
module CloudPubsub
|
|
6
|
-
# Middleware
|
|
7
|
-
module Middleware
|
|
8
|
-
# Middleware used for automatically acknowledging messages
|
|
9
|
-
class AutoRetry
|
|
10
|
-
attr_reader :max_attempts
|
|
11
|
-
|
|
12
|
-
def initialize(logger: nil, max_attempts: 1200)
|
|
13
|
-
@logger = logger
|
|
14
|
-
@max_attempts = max_attempts
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def call(message, **args)
|
|
18
|
-
succeeded = false
|
|
19
|
-
failed = false
|
|
20
|
-
yield(**args)
|
|
21
|
-
succeeded = true
|
|
22
|
-
rescue StandardError => e
|
|
23
|
-
failed = true
|
|
24
|
-
raise e
|
|
25
|
-
ensure
|
|
26
|
-
ack_or_reject(message, succeeded, failed, args)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
def ack_or_reject(message, succeeded, failed, args)
|
|
32
|
-
if succeeded
|
|
33
|
-
handle_success(message, args)
|
|
34
|
-
elsif failed && max_attempts_reached?(args)
|
|
35
|
-
handle_max_attempts_reached(message, args)
|
|
36
|
-
elsif failed
|
|
37
|
-
handle_failure(message, args)
|
|
38
|
-
else
|
|
39
|
-
handle_unfinished(message, args)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def handle_success(message, _args)
|
|
44
|
-
message.acknowledge!
|
|
45
|
-
logger.debug "Message(#{message.message_id}) was acknowledged"
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def max_attempts_reached?(args)
|
|
49
|
-
args.key?(:attempts) && args[:attempts] >= max_attempts
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def handle_max_attempts_reached(message, _args)
|
|
53
|
-
id = message.message_id
|
|
54
|
-
msg = 'number of attempts exceeded max attempts ' \
|
|
55
|
-
"of #{max_attempts}, acknowledging message"
|
|
56
|
-
logger.debug "Message(#{id}) failed, #{msg}"
|
|
57
|
-
message.acknowledge!
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def handle_failure(message, args)
|
|
61
|
-
id = message.message_id
|
|
62
|
-
seconds = calculate_backoff_seconds(message, args)
|
|
63
|
-
success = message.modify_ack_deadline!(seconds)
|
|
64
|
-
msg = "added #{success ? seconds : 0} seconds of delay to ack deadline"
|
|
65
|
-
logger.debug "Message(#{id}) failed, #{msg}" if success
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def handle_unfinished(message, _args)
|
|
69
|
-
id = message.message_id
|
|
70
|
-
message.reject!
|
|
71
|
-
logger.warn "Message(#{id}) was terminated from outside, rescheduling"
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def logger
|
|
75
|
-
@logger || CloudPubsub.logger
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def calculate_backoff_seconds(_message, args)
|
|
79
|
-
amt = if args.key?(:attempts)
|
|
80
|
-
count = args[:attempts]
|
|
81
|
-
# min + exponential + random smear
|
|
82
|
-
15 + count**4 + (rand(30) * (count + 1))
|
|
83
|
-
else
|
|
84
|
-
60
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
amt > 600 ? 600 : amt
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|