hanami-events-cloud_pubsub 2.9.0 → 3.0.4

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: a5ffe95cabc82141bd06ee9514ad0af66aaba9c5ebc719190e7cc9efba855274
4
- data.tar.gz: 119b219d3294f50b37a13daa36a4a55edf0d85f5ac14e82676fee3cad62f135a
3
+ metadata.gz: aee0ba4911c74d444d15ac8a68be7b29f6545bac4b5a3f334b82e7227c36f428
4
+ data.tar.gz: 1d04b3640314ab6cd95dcffe2c2e7e8f7d43c757ca7d82d47b012ffd2f5230b3
5
5
  SHA512:
6
- metadata.gz: a3475491db3dab17ab2fd423c056dca407977321223bd457903b3773bdbd7ef9080b2446e70305e8e64f136d6bd434c157b90ae72bd48f91bd388cb060005ee3
7
- data.tar.gz: 93bd30e26d6a85281f21dfd394f6aa7ea41a340459426f8b280f798e56b1fb3dc857390e6384e8d4605a286cbd313174eab2207e971e0c02374663cd91180744
6
+ metadata.gz: 88b2756beaf9b141768e60d119298bd2723882bf931000ffbf4ac81f1db5bfde8fab8458fcf25b92e9d4623538d6d7ef521116a511da2ea8545f6ee0e7741fdc
7
+ data.tar.gz: a059d2529907d76bc6f5be1c0e9f5298b5d883aef43e645a8b4d3ac6401bf00c8440fea93a8d924f2f06223ff93ff7c67588e4588a9a4a93baf84da2f01971e5
@@ -2,9 +2,10 @@
2
2
  inherit_from: .rubocop_todo.yml
3
3
 
4
4
  AllCops:
5
+ NewCops: enable
5
6
  Exclude:
6
7
  - bin/*
7
- TargetRubyVersion: 2.4
8
+ TargetRubyVersion: 2.5
8
9
 
9
10
  Metrics/BlockLength:
10
11
  Exclude:
@@ -1,13 +1,24 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2019-10-30 15:26:46 -0400 using RuboCop version 0.72.0.
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: 1
10
- # Configuration parameters: CountComments, ExcludedMethods.
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
@@ -8,9 +8,10 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- hanami-events-cloud_pubsub (2.9.0)
11
+ hanami-events-cloud_pubsub (3.0.4)
12
12
  dry-configurable (>= 0.8)
13
- google-cloud-pubsub (>= 0.38.1, < 1.7)
13
+ gapic-common (>= 0.3.4)
14
+ google-cloud-pubsub (>= 0.38.1, < 2.4)
14
15
  hanami-cli (~> 0.2)
15
16
  hanami-events (~> 0.2.0)
16
17
  rack
@@ -35,43 +36,45 @@ GEM
35
36
  dry-core (0.4.9)
36
37
  concurrent-ruby (~> 1.0)
37
38
  dry-equalizer (0.3.0)
38
- faraday (1.0.1)
39
+ faraday (1.1.0)
39
40
  multipart-post (>= 1.2, < 3)
41
+ ruby2_keywords
42
+ gapic-common (0.3.4)
43
+ google-protobuf (~> 3.12, >= 3.12.2)
44
+ googleapis-common-protos (>= 1.3.9, < 2.0)
45
+ googleapis-common-protos-types (>= 1.0.4, < 2.0)
46
+ googleauth (~> 0.9)
47
+ grpc (~> 1.25)
40
48
  google-cloud-core (1.5.0)
41
49
  google-cloud-env (~> 1.0)
42
50
  google-cloud-errors (~> 1.0)
43
- google-cloud-env (1.3.3)
51
+ google-cloud-env (1.4.0)
44
52
  faraday (>= 0.17.3, < 2.0)
45
53
  google-cloud-errors (1.0.1)
46
- google-cloud-pubsub (1.6.1)
54
+ google-cloud-pubsub (2.3.0)
47
55
  concurrent-ruby (~> 1.1)
48
- google-cloud-core (~> 1.2)
49
- google-gax (~> 1.8)
50
- googleapis-common-protos (>= 1.3.9, < 2.0)
51
- googleapis-common-protos-types (>= 1.0.4, < 2.0)
52
- grpc-google-iam-v1 (~> 0.6.9)
53
- google-gax (1.8.1)
54
- google-protobuf (~> 3.9)
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)
56
+ google-cloud-core (~> 1.5)
57
+ google-cloud-pubsub-v1 (~> 0.0)
58
+ google-cloud-pubsub-v1 (0.1.2)
59
+ gapic-common (~> 0.3)
60
+ google-cloud-errors (~> 1.0)
61
+ grpc-google-iam-v1 (>= 0.6.10, < 2.0)
62
+ google-protobuf (3.14.0)
60
63
  googleapis-common-protos (1.3.10)
61
64
  google-protobuf (~> 3.11)
62
65
  googleapis-common-protos-types (>= 1.0.5, < 2.0)
63
66
  grpc (~> 1.27)
64
67
  googleapis-common-protos-types (1.0.5)
65
68
  google-protobuf (~> 3.11)
66
- googleauth (0.13.1)
69
+ googleauth (0.14.0)
67
70
  faraday (>= 0.17.3, < 2.0)
68
71
  jwt (>= 1.4, < 3.0)
69
72
  memoist (~> 0.16)
70
73
  multi_json (~> 1.11)
71
74
  os (>= 0.9, < 2.0)
72
75
  signet (~> 0.14)
73
- grpc (1.30.2)
74
- google-protobuf (~> 3.12)
76
+ grpc (1.34.0)
77
+ google-protobuf (~> 3.13)
75
78
  googleapis-common-protos-types (~> 1.0)
76
79
  grpc-google-iam-v1 (0.6.10)
77
80
  google-protobuf (~> 3.11)
@@ -83,7 +86,7 @@ GEM
83
86
  hanami-utils (1.3.6)
84
87
  concurrent-ruby (~> 1.0)
85
88
  transproc (~> 1.0)
86
- jwt (2.2.1)
89
+ jwt (2.2.2)
87
90
  memoist (0.16.2)
88
91
  method_source (1.0.0)
89
92
  multi_json (1.15.0)
@@ -96,14 +99,13 @@ GEM
96
99
  pry (0.13.1)
97
100
  coderay (~> 1.1)
98
101
  method_source (~> 1.0)
99
- public_suffix (4.0.5)
102
+ public_suffix (4.0.6)
100
103
  rack (2.2.3)
101
104
  rainbow (3.0.0)
102
105
  rake (13.0.1)
103
106
  regexp_parser (1.7.1)
104
107
  request_id (0.4.3)
105
108
  rexml (3.2.4)
106
- rly (0.2.3)
107
109
  rspec (3.9.0)
108
110
  rspec-core (~> 3.9.0)
109
111
  rspec-expectations (~> 3.9.0)
@@ -129,6 +131,7 @@ GEM
129
131
  rubocop-ast (0.3.0)
130
132
  parser (>= 2.7.1.4)
131
133
  ruby-progressbar (1.10.1)
134
+ ruby2_keywords (0.0.2)
132
135
  signet (0.14.0)
133
136
  addressable (~> 2.3)
134
137
  faraday (>= 0.17.3, < 2.0)
@@ -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(STDOUT))
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)
@@ -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 'google-cloud-pubsub', '>= 0.38.1', '< 1.7'
28
+ spec.add_dependency 'gapic-common', '>= 0.3.4'
29
+ spec.add_dependency 'google-cloud-pubsub', '>= 0.38.1', '< 2.4'
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(STDOUT)
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, payload, **message_opts)
32
+ def broadcast(name, input_payload, **message_opts)
33
33
  event_name = namespaced(name)
34
34
  topic = topic_for event_name
35
- payload = serializer.serialize(payload)
36
- attributes = { id: SecureRandom.uuid, event_name: event_name }
37
-
38
- middleware.invoke(payload, **attributes, **message_opts) do |*args|
39
- topic.publish_async(*args) do |result|
40
- logger.info "Published event #{result.inspect}"
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 Metrics/LineLength
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 Metrics/LineLength
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(STDOUT), reader: true
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 }
@@ -102,8 +102,8 @@ module Hanami
102
102
  end
103
103
 
104
104
  def shutdown
105
- STDOUT.flush
106
- STDERR.flush
105
+ $stdout.flush
106
+ $stderr.flush
107
107
  runner.gracefully_shutdown
108
108
  ensure
109
109
  @finished_shutting_down = true
@@ -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
- :subscriber_opts,
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
- @subscriber_opts = CloudPubsub.config.subscriber.to_h.merge(subscriber_opts)
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(**subscriber_opts) do |message|
40
- handle_message(message)
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
 
@@ -83,8 +85,10 @@ module Hanami
83
85
 
84
86
  def run_handler(message)
85
87
  middleware.invoke(message) { handler.call(message) }
88
+ message.ack!
86
89
  rescue StandardError => e
87
90
  run_error_handlers(e, message)
91
+ message.nack! if CloudPubsub.config.auto_retry.enabled
88
92
  raise
89
93
  end
90
94
 
@@ -120,7 +124,30 @@ 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
+ rescue StandardError => e
147
+ run_error_handlers(e, "Faled to apply retry options (see https://github.com/googleapis/google-cloud-ruby/issues/8237)")
148
+ end
123
149
  end
150
+ # rubocop:enable Metrics/ClassLength:
124
151
  end
125
152
  end
126
153
  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| '' + lis.format }.join("\n")}
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
- begin
118
- handler.call(adapter)
119
- rescue StandardError => e
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
@@ -48,7 +48,7 @@ module Hanami
48
48
  end
49
49
 
50
50
  def join_backtrace(pretty_backtrace)
51
- pretty_backtrace.map! { |line| "║\t" + line }
51
+ pretty_backtrace.map! { |line| "║\t#{line}" }
52
52
  pretty_backtrace << '║'
53
53
  pretty_backtrace.join("\n")
54
54
  end
@@ -3,7 +3,7 @@
3
3
  module Hanami
4
4
  module Events
5
5
  module CloudPubsub
6
- VERSION = '2.9.0'
6
+ VERSION = '3.0.4'
7
7
  end
8
8
  end
9
9
  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: 2.9.0
4
+ version: 3.0.4
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-08-06 00:00:00.000000000 Z
11
+ date: 2020-12-06 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.7'
50
+ version: '2.4'
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.7'
60
+ version: '2.4'
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,15 +216,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
216
  requirements:
204
217
  - - ">="
205
218
  - !ruby/object:Gem::Version
206
- version: '0'
219
+ version: 2.5.0
207
220
  required_rubygems_version: !ruby/object:Gem::Requirement
208
221
  requirements:
209
222
  - - ">="
210
223
  - !ruby/object:Gem::Version
211
224
  version: '0'
212
225
  requirements: []
213
- rubygems_version: 3.1.2
214
- signing_key:
226
+ rubygems_version: 3.0.3
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