hermes_messenger_of_the_gods 2.3.2 → 2.4.0.pre1

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: 45e46de302befb016769708d8ec0e3d500e1dc3d83f3c2759eb37e089df3f54d
4
- data.tar.gz: f678ce9af82af7750fce178b117c2e4fcc79a133d1e79d132d1ec9e29b9428c7
3
+ metadata.gz: 9db3c55e00b3b57edc8fe5d4f2707d4d0d5660bc916190412e923adef5541966
4
+ data.tar.gz: b290f95419766f1931426c78fc48b7db740e4c73e538e9b9f137dd54cc63161e
5
5
  SHA512:
6
- metadata.gz: b4bfd0c75c08192c83866e6a5c744b9b4670a84858c93afcf24aab0af4ab8edb2ac2f7de7dc2d4dadc02eb27e906b34293a16d1fa0e5a75c35a35ba79618f30c
7
- data.tar.gz: 64c3bdc04eaeebdfa0a73c0f7c0654f2274c2ef9a8f44f145b868b7805be971303a6b5e4df24b89522c7e348788dee68c67634e153b854820d93a72ae431a5c2
6
+ metadata.gz: 2cba3abed264d740bb49085085e1d8e21655eb62c9de8ce89abeaeaa848edfc8cc21db04c79c1a6a2a8a415d55fa9be9e55d3ff241e0e1ab10a81b207233e23b
7
+ data.tar.gz: cc3d65d5d64cf1039c64e32098b956b5793a061303eeb792d2d5115a1b1f0ef8cb99e539993f02ed8869523ef300adffa9e6dca0c0721c55154b970a49ec4656
@@ -14,11 +14,7 @@ module HermesMessengerOfTheGods
14
14
  include ActiveModel::Model
15
15
  include HermesMessengerOfTheGods::Concerns::Base
16
16
 
17
- attr_accessor :targeted_endpoints
18
-
19
- def original_message
20
- @original_message
21
- end
17
+ attr_accessor :targeted_endpoints, :original_message, :source_endpoint
22
18
 
23
19
  def initialize(options = {})
24
20
  @monitor = Monitor.new
@@ -54,6 +50,15 @@ module HermesMessengerOfTheGods
54
50
  end
55
51
  end
56
52
 
53
+ def retry_at(future_time_or_seconds_in_future)
54
+ raise 'unable to set visiblity' if source_endpoint.nil? || original_message.nil?
55
+ unless source_endpoint.respond_to?(:set_reexecution_time)
56
+ raise "endpoint type doesn't support setting execution time"
57
+ end
58
+
59
+ source_endpoint.set_reexecution_time(original_message, future_time_or_seconds_in_future)
60
+ end
61
+
57
62
  def dispatch!(endpoint_args: {})
58
63
  run_callbacks :dispatch do
59
64
  validate!
@@ -65,7 +70,7 @@ module HermesMessengerOfTheGods
65
70
  endpoint.dispatch!(self, endpoint_args) unless HermesMessengerOfTheGods.config.stub_dispatch
66
71
  register_success(ep_name, endpoint.result)
67
72
  rescue StandardError => e
68
- error(e)
73
+ say_error(e)
69
74
  register_failure(ep_name, e)
70
75
  ensure
71
76
  endpoint.teardown
@@ -155,13 +160,13 @@ module HermesMessengerOfTheGods
155
160
  _circuit_breaker_errors
156
161
  end
157
162
 
158
-
159
163
  def max_consecutive_failures
160
164
  _max_consecutive_failures
161
165
  end
162
166
 
163
167
  def max_consecutive_failures=(val)
164
168
  raise 'Expected an Integer' unless val.is_a?(Integer) || val.is_a?(NilClass)
169
+
165
170
  self._max_consecutive_failures = val
166
171
  end
167
172
 
@@ -169,12 +174,12 @@ module HermesMessengerOfTheGods
169
174
  val ||= {}
170
175
  raise 'Expected a hash' unless val.is_a?(Hash)
171
176
 
172
- val.each do |err, actions|
177
+ val.each do |err, _actions|
173
178
  val[err][:sleep] ||= 0
174
179
  val[err][:fatal] ||= false
175
180
  end
176
181
 
177
- val.each do |err, actions|
182
+ val.each do |_err, actions|
178
183
  raise ':sleep must be a number' unless actions[:sleep].is_a?(Numeric)
179
184
  raise ':fatal must be a boolean' unless [true, false].include?(actions[:fatal])
180
185
  end
@@ -183,9 +188,7 @@ module HermesMessengerOfTheGods
183
188
  end
184
189
 
185
190
  def endpoints=(val)
186
- unless val.is_a?(Hash)
187
- raise 'Endpoints expects a hash {endpoint_name: endpoint_handler}'
188
- end
191
+ raise 'Endpoints expects a hash {endpoint_name: endpoint_handler}' unless val.is_a?(Hash)
189
192
 
190
193
  self._endpoints = val
191
194
  end
@@ -40,7 +40,9 @@ module HermesMessengerOfTheGods
40
40
  endpoint.work_off do |job, original_message|
41
41
  self.last_task_performed = Time.now
42
42
 
43
- built_job = deserialize(job, original_message)
43
+ built_job = deserialize(job)
44
+ built_job.original_message = original_message
45
+ built_job.source_endpoint = endpoint
44
46
  instrument(:starting_job, job: built_job)
45
47
  built_job.validate! if built_job.respond_to?(:validate!)
46
48
  run_job(built_job)
@@ -99,12 +101,10 @@ module HermesMessengerOfTheGods
99
101
  self.consecutive_failures += 1
100
102
  end
101
103
 
102
- def deserialize(raw_job, original_message)
104
+ def deserialize(raw_job)
103
105
  instrument(:deserialization, job: raw_job) do
104
106
  deserialize_method = self.class.deserialize_method || :from_message
105
- self.class.deserialize_with.send(deserialize_method, raw_job).tap do |obj|
106
- obj.instance_variable_set :@original_message, original_message
107
- end
107
+ self.class.deserialize_with.send(deserialize_method, raw_job)
108
108
  end
109
109
  end
110
110
 
@@ -13,6 +13,7 @@ module HermesMessengerOfTheGods
13
13
  def initialize(*args)
14
14
  super
15
15
  @message_mux = Monitor.new
16
+ @work_start_time_mux = Monitor.new
16
17
  end
17
18
 
18
19
  def poller
@@ -24,6 +25,14 @@ module HermesMessengerOfTheGods
24
25
  )
25
26
  end
26
27
 
28
+ def work_start_time
29
+ @work_start_time_mux.synchronize { @work_start_time }
30
+ end
31
+
32
+ def reset_work_start_time!
33
+ @work_start_time_mux.synchronize { @work_start_time = Time.now }
34
+ end
35
+
27
36
  def inflight_messages
28
37
  @message_mux.synchronize { @inflight_messages ||= [] }
29
38
  end
@@ -43,7 +52,7 @@ module HermesMessengerOfTheGods
43
52
  #
44
53
  # Break from polling
45
54
  def shutdown!
46
- warn 'Shutdown command received'
55
+ warn 'Reveived shutdown signal'
47
56
  @shutdown = true
48
57
  end
49
58
 
@@ -67,15 +76,35 @@ module HermesMessengerOfTheGods
67
76
  shutting_down? ? :shutdown : work_message(msg, &blk)
68
77
  end
69
78
 
70
- poller.delete_messages(completion_results[true]) unless completion_results.fetch(true, []).empty?
79
+ unless completion_results.fetch(true, []).empty?
80
+ poller.delete_messages(completion_results[true] & inflight_messages)
81
+ end
71
82
  # Messages skipped due to shutdowns get their visibility set back to 0 so they restart
72
83
  # normal failed jobs will be left in queue until their visibility timeout expires to indicate a backoff
73
- set_message_visibility(completion_results[:shutdown], 0) unless completion_results.fetch(:shutdown,
74
- []).empty?
84
+ unless completion_results.fetch(:shutdown, []).empty?
85
+ set_message_visibility(completion_results[:shutdown] & inflight_messages, 0)
86
+ end
75
87
  end
76
88
  end
77
89
  end
78
90
 
91
+ def set_reexecution_time(message, duration_or_time)
92
+ # You can pass a time to re-run at or you can pass the seconds in the future to run at
93
+ extend_time = if duration_or_time.is_a?(Time)
94
+ duration_or_time - Time.now
95
+ else
96
+ duration_or_time
97
+ end
98
+
99
+ message_array = [message]
100
+
101
+ @message_mux.synchronize do
102
+ set_message_visibility(message_array, (Time.now - work_start_time) + extend_time)
103
+
104
+ @inflight_messages -= message_array
105
+ end
106
+ end
107
+
79
108
  def work_message(message)
80
109
  message_body = decode_message(message)
81
110
 
@@ -130,6 +159,7 @@ module HermesMessengerOfTheGods
130
159
  end
131
160
 
132
161
  def working_messages
162
+ reset_work_start_time!
133
163
  thread = start_visibility_update_thread
134
164
  yield
135
165
  ensure
@@ -137,15 +167,14 @@ module HermesMessengerOfTheGods
137
167
  end
138
168
 
139
169
  def start_visibility_update_thread
140
- start_work_time = Time.now
141
170
  Thread.new do
142
171
  loop do
143
- new_time = (Time.now - start_work_time) + VISIBILITY_EXTEND_DURATION
172
+ new_time = (Time.now - work_start_time) + VISIBILITY_EXTEND_DURATION
144
173
  set_message_visibility(inflight_messages, new_time)
145
174
  sleep VISIBILITY_EXTEND_FREQUENCY
146
175
  rescue StandardError => e
147
- warn 'Error received trying to extend visibility'
148
- warn e.message
176
+ say_warn 'Error received trying to extend visibility'
177
+ say_warn e.message
149
178
 
150
179
  raise
151
180
  end
@@ -6,7 +6,7 @@ module HermesMessengerOfTheGods
6
6
 
7
7
  included do
8
8
  Logger::Severity.constants.each do |sev|
9
- define_method(sev.downcase) do |msg = nil, &blk|
9
+ define_method("say_#{sev.downcase}") do |msg = nil, &blk|
10
10
  say("Logger::#{sev}".constantize, msg, &blk)
11
11
  end
12
12
  end
@@ -13,41 +13,41 @@ module HermesMessengerOfTheGods
13
13
 
14
14
  @subscriptions = [
15
15
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.worker.starting') do |*_, payload|
16
- payload[:worker].info { "Starting Worker" }
16
+ payload[:worker].say_info { "Starting Worker" }
17
17
  end,
18
18
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.worker.run_job') do |_, start, finish, _, payload|
19
- payload[:worker].debug { "Completed #{to_log_s(payload[:job])} in #{finish - start}s" }
19
+ payload[:worker].say_debug { "Completed #{to_log_s(payload[:job])} in #{finish - start}s" }
20
20
  end,
21
21
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.worker.starting_job') do |*_, payload|
22
- payload[:worker].info { "Starting Job #{to_log_s(payload[:job])}" }
22
+ payload[:worker].say_info { "Starting Job #{to_log_s(payload[:job])}" }
23
23
  end,
24
24
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.worker.success') do |*_, payload|
25
- payload[:worker].info { "Finished Job #{to_log_s(payload[:job])}" }
25
+ payload[:worker].say_info { "Finished Job #{to_log_s(payload[:job])}" }
26
26
  end,
27
27
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.worker.failure') do |*_, payload|
28
- payload[:worker].error { "Error in #{to_log_s(payload[:job])}: #{payload[:error].message}" }
29
- payload[:worker].debug { "backtrace: #{payload[:error].backtrace}" }
28
+ payload[:worker].say_error { "Error in #{to_log_s(payload[:job])}: #{payload[:error].message}" }
29
+ payload[:worker].say_debug { "backtrace: #{payload[:error].backtrace}" }
30
30
  end,
31
31
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.worker.fatal_error') do |*_, payload|
32
- payload[:worker].error { "Fatal Error: #{to_log_s(payload[:job])}: #{payload[:exception].message}" }
33
- payload[:worker].debug { "backtrace: #{payload[:exception].backtrace}" }
32
+ payload[:worker].say_error { "Fatal Error: #{to_log_s(payload[:job])}: #{payload[:exception].message}" }
33
+ payload[:worker].say_debug { "backtrace: #{payload[:exception].backtrace}" }
34
34
  end,
35
35
  # Message Output
36
36
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.message.dispatch') do |_, _start, _finish, _, payload|
37
- payload[:message].info { "Dispatch complete in #{to_log_s(payload[:job])}s" }
37
+ payload[:message].say_info { "Dispatch complete in #{to_log_s(payload[:job])}s" }
38
38
  end,
39
39
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.message.dispatch_failure') do |*_, payload|
40
- payload[:message].debug { "Dispatch failure to #{to_log_s(payload[:job])}: #{payload[:exception].inspect}" }
40
+ payload[:message].say_debug { "Dispatch failure to #{to_log_s(payload[:job])}: #{payload[:exception].inspect}" }
41
41
  end,
42
42
  # Endpoint Output
43
43
  ActiveSupport::Notifications.subscribe('hermes_messenger_of_the_gods.endpoint.dispatch') do |_, start, finish, _, payload|
44
- payload[:endpoint].info { "Dispatch complete in #{finish - start}s #{" FAILED" if payload.has_key?(:exception)}" }
44
+ payload[:endpoint].say_info { "Dispatch complete in #{finish - start}s #{" FAILED" if payload.has_key?(:exception)}" }
45
45
  end,
46
46
  ActiveSupport::Notifications.subscribe(/hermes_messenger_of_the_gods.endpoint.(dispatch|final)_failure/) do |name, *_, payload|
47
- payload[:endpoint].debug { "Dispatch #{"final " if name.include?('final_')} failure ##{payload[:try]} to #{payload[:endpoint_name]}: #{payload[:exception].inspect}" }
47
+ payload[:endpoint].say_debug { "Dispatch #{"final " if name.include?('final_')} failure ##{payload[:try]} to #{payload[:endpoint_name]}: #{payload[:exception].inspect}" }
48
48
  end,
49
49
  ActiveSupport::Notifications.subscribe(/hermes_messenger_of_the_gods.endpoint.read_failure/) do |name, *_, payload|
50
- payload[:endpoint].error { "A message was received that could not be decoded: #{payload[:exception].message}" }
50
+ payload[:endpoint].say_error { "A message was received that could not be decoded: #{payload[:exception].message}" }
51
51
  end,
52
52
  ]
53
53
  end
@@ -1,3 +1,3 @@
1
1
  module HermesMessengerOfTheGods
2
- VERSION = '2.3.2'
2
+ VERSION = '2.4.0.pre1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hermes_messenger_of_the_gods
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.4.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Malinconico
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-07-08 00:00:00.000000000 Z
12
+ date: 2022-08-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -222,18 +222,10 @@ files:
222
222
  - lib/hermes_messenger_of_the_gods/testing/rspec_helpers.rb
223
223
  - lib/hermes_messenger_of_the_gods/version.rb
224
224
  - packageGems.sh
225
- - vendor/cache/activemodel-6.1.4.1.gem
226
- - vendor/cache/activesupport-6.1.4.1.gem
227
225
  - vendor/cache/addressable-2.8.0.gem
228
226
  - vendor/cache/aws-eventstream-1.2.0.gem
229
- - vendor/cache/aws-partitions-1.509.0.gem
230
- - vendor/cache/aws-sdk-core-3.121.1.gem
231
- - vendor/cache/aws-sdk-sns-1.45.0.gem
232
- - vendor/cache/aws-sdk-sqs-1.44.0.gem
233
- - vendor/cache/aws-sigv4-1.4.0.gem
234
227
  - vendor/cache/codeclimate-test-reporter-1.0.7.gem
235
228
  - vendor/cache/coderay-1.1.3.gem
236
- - vendor/cache/concurrent-ruby-1.1.9.gem
237
229
  - vendor/cache/coveralls_reborn-0.22.0.gem
238
230
  - vendor/cache/crack-0.4.5.gem
239
231
  - vendor/cache/diff-lcs-1.4.4.gem
@@ -244,11 +236,8 @@ files:
244
236
  - vendor/cache/grpc-1.40.0-universal-darwin.gem
245
237
  - vendor/cache/grpc-1.40.0-x86_64-linux.gem
246
238
  - vendor/cache/hashdiff-1.0.1.gem
247
- - vendor/cache/i18n-1.8.10.gem
248
- - vendor/cache/jmespath-1.4.0.gem
249
239
  - vendor/cache/memory_profiler-1.0.0.gem
250
240
  - vendor/cache/method_source-1.0.0.gem
251
- - vendor/cache/minitest-5.14.4.gem
252
241
  - vendor/cache/pry-0.14.1.gem
253
242
  - vendor/cache/public_suffix-4.0.6.gem
254
243
  - vendor/cache/rake-10.5.0.gem
@@ -267,9 +256,7 @@ files:
267
256
  - vendor/cache/thor-1.1.0.gem
268
257
  - vendor/cache/timecop-0.9.4.gem
269
258
  - vendor/cache/tins-1.29.1.gem
270
- - vendor/cache/tzinfo-2.0.4.gem
271
259
  - vendor/cache/webmock-3.14.0.gem
272
- - vendor/cache/zeitwerk-2.4.2.gem
273
260
  homepage:
274
261
  licenses: []
275
262
  metadata:
@@ -285,9 +272,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
285
272
  version: '0'
286
273
  required_rubygems_version: !ruby/object:Gem::Requirement
287
274
  requirements:
288
- - - ">="
275
+ - - ">"
289
276
  - !ruby/object:Gem::Version
290
- version: '0'
277
+ version: 1.3.1
291
278
  requirements: []
292
279
  rubygems_version: 3.2.22
293
280
  signing_key:
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file