deimos-ruby 1.7.0.pre.beta1 → 1.8.1.pre.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -4
- data/CHANGELOG.md +50 -0
- data/Gemfile.lock +109 -75
- data/README.md +147 -16
- data/deimos-ruby.gemspec +4 -2
- data/docs/ARCHITECTURE.md +144 -0
- data/docs/CONFIGURATION.md +4 -0
- data/lib/deimos.rb +8 -7
- data/lib/deimos/active_record_consume/batch_consumption.rb +159 -0
- data/lib/deimos/active_record_consume/batch_slicer.rb +27 -0
- data/lib/deimos/active_record_consume/message_consumption.rb +58 -0
- data/lib/deimos/active_record_consume/schema_model_converter.rb +52 -0
- data/lib/deimos/active_record_consumer.rb +33 -75
- data/lib/deimos/batch_consumer.rb +2 -142
- data/lib/deimos/config/configuration.rb +8 -10
- data/lib/deimos/consume/batch_consumption.rb +150 -0
- data/lib/deimos/consume/message_consumption.rb +94 -0
- data/lib/deimos/consumer.rb +79 -72
- data/lib/deimos/instrumentation.rb +10 -5
- data/lib/deimos/kafka_message.rb +1 -1
- data/lib/deimos/kafka_topic_info.rb +21 -2
- data/lib/deimos/message.rb +6 -1
- data/lib/deimos/schema_backends/avro_base.rb +33 -1
- data/lib/deimos/schema_backends/avro_schema_coercer.rb +30 -11
- data/lib/deimos/schema_backends/base.rb +21 -2
- data/lib/deimos/utils/db_poller.rb +6 -6
- data/lib/deimos/utils/db_producer.rb +57 -15
- data/lib/deimos/utils/deadlock_retry.rb +68 -0
- data/lib/deimos/utils/lag_reporter.rb +19 -26
- data/lib/deimos/utils/schema_controller_mixin.rb +111 -0
- data/lib/deimos/version.rb +1 -1
- data/lib/generators/deimos/active_record/templates/migration.rb.tt +28 -0
- data/lib/generators/deimos/active_record/templates/model.rb.tt +5 -0
- data/lib/generators/deimos/active_record_generator.rb +79 -0
- data/lib/generators/deimos/db_backend/templates/migration +1 -0
- data/lib/generators/deimos/db_backend/templates/rails3_migration +1 -0
- data/spec/active_record_batch_consumer_spec.rb +481 -0
- data/spec/active_record_consume/batch_slicer_spec.rb +42 -0
- data/spec/active_record_consume/schema_model_converter_spec.rb +105 -0
- data/spec/active_record_consumer_spec.rb +3 -11
- data/spec/batch_consumer_spec.rb +24 -7
- data/spec/config/configuration_spec.rb +4 -0
- data/spec/consumer_spec.rb +6 -6
- data/spec/deimos_spec.rb +57 -49
- data/spec/generators/active_record_generator_spec.rb +56 -0
- data/spec/handlers/my_batch_consumer.rb +6 -1
- data/spec/handlers/my_consumer.rb +6 -1
- data/spec/kafka_listener_spec.rb +54 -0
- data/spec/kafka_topic_info_spec.rb +39 -16
- data/spec/message_spec.rb +19 -0
- data/spec/producer_spec.rb +34 -0
- data/spec/schemas/com/my-namespace/Generated.avsc +71 -0
- data/spec/schemas/com/my-namespace/MyNestedSchema.avsc +55 -0
- data/spec/schemas/com/my-namespace/MySchemaCompound-key.avsc +18 -0
- data/spec/schemas/com/my-namespace/Wibble.avsc +43 -0
- data/spec/schemas/com/my-namespace/request/Index.avsc +11 -0
- data/spec/schemas/com/my-namespace/request/UpdateRequest.avsc +11 -0
- data/spec/schemas/com/my-namespace/response/Index.avsc +11 -0
- data/spec/schemas/com/my-namespace/response/UpdateResponse.avsc +11 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/utils/db_poller_spec.rb +2 -2
- data/spec/utils/db_producer_spec.rb +84 -10
- data/spec/utils/deadlock_retry_spec.rb +74 -0
- data/spec/utils/lag_reporter_spec.rb +29 -22
- data/spec/utils/schema_controller_mixin_spec.rb +68 -0
- metadata +87 -30
- data/lib/deimos/base_consumer.rb +0 -100
- data/lib/deimos/utils/executor.rb +0 -124
- data/lib/deimos/utils/platform_schema_validation.rb +0 -0
- data/lib/deimos/utils/signal_handler.rb +0 -68
- data/spec/utils/executor_spec.rb +0 -53
- data/spec/utils/signal_handler_spec.rb +0 -16
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deimos-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1.pre.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Orner
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05
|
11
|
+
date: 2020-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: avro_turf
|
@@ -53,19 +53,19 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0.7'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: sigurd
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :
|
61
|
+
version: 0.0.1
|
62
|
+
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.0.1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: activerecord-import
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.9'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: database_cleaner
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.7'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.7'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: ddtrace
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -198,20 +212,14 @@ dependencies:
|
|
198
212
|
requirements:
|
199
213
|
- - "~>"
|
200
214
|
- !ruby/object:Gem::Version
|
201
|
-
version: '
|
202
|
-
- - ">="
|
203
|
-
- !ruby/object:Gem::Version
|
204
|
-
version: 5.2.4.2
|
215
|
+
version: '6'
|
205
216
|
type: :development
|
206
217
|
prerelease: false
|
207
218
|
version_requirements: !ruby/object:Gem::Requirement
|
208
219
|
requirements:
|
209
220
|
- - "~>"
|
210
221
|
- !ruby/object:Gem::Version
|
211
|
-
version: '
|
212
|
-
- - ">="
|
213
|
-
- !ruby/object:Gem::Version
|
214
|
-
version: 5.2.4.2
|
222
|
+
version: '6'
|
215
223
|
- !ruby/object:Gem::Dependency
|
216
224
|
name: rake
|
217
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -254,6 +262,20 @@ dependencies:
|
|
254
262
|
- - "~>"
|
255
263
|
- !ruby/object:Gem::Version
|
256
264
|
version: '0.3'
|
265
|
+
- !ruby/object:Gem::Dependency
|
266
|
+
name: rspec-rails
|
267
|
+
requirement: !ruby/object:Gem::Requirement
|
268
|
+
requirements:
|
269
|
+
- - "~>"
|
270
|
+
- !ruby/object:Gem::Version
|
271
|
+
version: '4'
|
272
|
+
type: :development
|
273
|
+
prerelease: false
|
274
|
+
version_requirements: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - "~>"
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: '4'
|
257
279
|
- !ruby/object:Gem::Dependency
|
258
280
|
name: rubocop
|
259
281
|
requirement: !ruby/object:Gem::Requirement
|
@@ -296,7 +318,7 @@ dependencies:
|
|
296
318
|
- - "~>"
|
297
319
|
- !ruby/object:Gem::Version
|
298
320
|
version: '1.3'
|
299
|
-
description:
|
321
|
+
description:
|
300
322
|
email:
|
301
323
|
- daniel.orner@wishabi.com
|
302
324
|
executables:
|
@@ -323,10 +345,15 @@ files:
|
|
323
345
|
- bin/deimos
|
324
346
|
- deimos-ruby.gemspec
|
325
347
|
- docker-compose.yml
|
348
|
+
- docs/ARCHITECTURE.md
|
326
349
|
- docs/CONFIGURATION.md
|
327
350
|
- docs/DATABASE_BACKEND.md
|
328
351
|
- docs/PULL_REQUEST_TEMPLATE.md
|
329
352
|
- lib/deimos.rb
|
353
|
+
- lib/deimos/active_record_consume/batch_consumption.rb
|
354
|
+
- lib/deimos/active_record_consume/batch_slicer.rb
|
355
|
+
- lib/deimos/active_record_consume/message_consumption.rb
|
356
|
+
- lib/deimos/active_record_consume/schema_model_converter.rb
|
330
357
|
- lib/deimos/active_record_consumer.rb
|
331
358
|
- lib/deimos/active_record_producer.rb
|
332
359
|
- lib/deimos/backends/base.rb
|
@@ -334,11 +361,12 @@ files:
|
|
334
361
|
- lib/deimos/backends/kafka.rb
|
335
362
|
- lib/deimos/backends/kafka_async.rb
|
336
363
|
- lib/deimos/backends/test.rb
|
337
|
-
- lib/deimos/base_consumer.rb
|
338
364
|
- lib/deimos/batch_consumer.rb
|
339
365
|
- lib/deimos/config/configurable.rb
|
340
366
|
- lib/deimos/config/configuration.rb
|
341
367
|
- lib/deimos/config/phobos_config.rb
|
368
|
+
- lib/deimos/consume/batch_consumption.rb
|
369
|
+
- lib/deimos/consume/message_consumption.rb
|
342
370
|
- lib/deimos/consumer.rb
|
343
371
|
- lib/deimos/instrumentation.rb
|
344
372
|
- lib/deimos/kafka_message.rb
|
@@ -368,12 +396,14 @@ files:
|
|
368
396
|
- lib/deimos/tracing/provider.rb
|
369
397
|
- lib/deimos/utils/db_poller.rb
|
370
398
|
- lib/deimos/utils/db_producer.rb
|
371
|
-
- lib/deimos/utils/
|
399
|
+
- lib/deimos/utils/deadlock_retry.rb
|
372
400
|
- lib/deimos/utils/inline_consumer.rb
|
373
401
|
- lib/deimos/utils/lag_reporter.rb
|
374
|
-
- lib/deimos/utils/
|
375
|
-
- lib/deimos/utils/signal_handler.rb
|
402
|
+
- lib/deimos/utils/schema_controller_mixin.rb
|
376
403
|
- lib/deimos/version.rb
|
404
|
+
- lib/generators/deimos/active_record/templates/migration.rb.tt
|
405
|
+
- lib/generators/deimos/active_record/templates/model.rb.tt
|
406
|
+
- lib/generators/deimos/active_record_generator.rb
|
377
407
|
- lib/generators/deimos/db_backend/templates/migration
|
378
408
|
- lib/generators/deimos/db_backend/templates/rails3_migration
|
379
409
|
- lib/generators/deimos/db_backend_generator.rb
|
@@ -381,6 +411,9 @@ files:
|
|
381
411
|
- lib/generators/deimos/db_poller/templates/rails3_migration
|
382
412
|
- lib/generators/deimos/db_poller_generator.rb
|
383
413
|
- lib/tasks/deimos.rake
|
414
|
+
- spec/active_record_batch_consumer_spec.rb
|
415
|
+
- spec/active_record_consume/batch_slicer_spec.rb
|
416
|
+
- spec/active_record_consume/schema_model_converter_spec.rb
|
384
417
|
- spec/active_record_consumer_spec.rb
|
385
418
|
- spec/active_record_producer_spec.rb
|
386
419
|
- spec/backends/base_spec.rb
|
@@ -392,10 +425,13 @@ files:
|
|
392
425
|
- spec/config/configuration_spec.rb
|
393
426
|
- spec/consumer_spec.rb
|
394
427
|
- spec/deimos_spec.rb
|
428
|
+
- spec/generators/active_record_generator_spec.rb
|
395
429
|
- spec/handlers/my_batch_consumer.rb
|
396
430
|
- spec/handlers/my_consumer.rb
|
431
|
+
- spec/kafka_listener_spec.rb
|
397
432
|
- spec/kafka_source_spec.rb
|
398
433
|
- spec/kafka_topic_info_spec.rb
|
434
|
+
- spec/message_spec.rb
|
399
435
|
- spec/phobos.bad_db.yml
|
400
436
|
- spec/phobos.yml
|
401
437
|
- spec/producer_spec.rb
|
@@ -405,21 +441,29 @@ files:
|
|
405
441
|
- spec/schema_backends/avro_schema_registry_spec.rb
|
406
442
|
- spec/schema_backends/avro_validation_spec.rb
|
407
443
|
- spec/schema_backends/base_spec.rb
|
444
|
+
- spec/schemas/com/my-namespace/Generated.avsc
|
445
|
+
- spec/schemas/com/my-namespace/MyNestedSchema.avsc
|
408
446
|
- spec/schemas/com/my-namespace/MySchema-key.avsc
|
409
447
|
- spec/schemas/com/my-namespace/MySchema.avsc
|
448
|
+
- spec/schemas/com/my-namespace/MySchemaCompound-key.avsc
|
410
449
|
- spec/schemas/com/my-namespace/MySchemaWithBooleans.avsc
|
411
450
|
- spec/schemas/com/my-namespace/MySchemaWithDateTimes.avsc
|
412
451
|
- spec/schemas/com/my-namespace/MySchemaWithId.avsc
|
413
452
|
- spec/schemas/com/my-namespace/MySchemaWithUniqueId.avsc
|
453
|
+
- spec/schemas/com/my-namespace/Wibble.avsc
|
414
454
|
- spec/schemas/com/my-namespace/Widget.avsc
|
415
455
|
- spec/schemas/com/my-namespace/WidgetTheSecond.avsc
|
456
|
+
- spec/schemas/com/my-namespace/request/Index.avsc
|
457
|
+
- spec/schemas/com/my-namespace/request/UpdateRequest.avsc
|
458
|
+
- spec/schemas/com/my-namespace/response/Index.avsc
|
459
|
+
- spec/schemas/com/my-namespace/response/UpdateResponse.avsc
|
416
460
|
- spec/spec_helper.rb
|
417
461
|
- spec/utils/db_poller_spec.rb
|
418
462
|
- spec/utils/db_producer_spec.rb
|
419
|
-
- spec/utils/
|
463
|
+
- spec/utils/deadlock_retry_spec.rb
|
420
464
|
- spec/utils/lag_reporter_spec.rb
|
421
465
|
- spec/utils/platform_schema_validation_spec.rb
|
422
|
-
- spec/utils/
|
466
|
+
- spec/utils/schema_controller_mixin_spec.rb
|
423
467
|
- support/deimos-solo.png
|
424
468
|
- support/deimos-with-name-next.png
|
425
469
|
- support/deimos-with-name.png
|
@@ -428,7 +472,7 @@ homepage: ''
|
|
428
472
|
licenses:
|
429
473
|
- Apache-2.0
|
430
474
|
metadata: {}
|
431
|
-
post_install_message:
|
475
|
+
post_install_message:
|
432
476
|
rdoc_options: []
|
433
477
|
require_paths:
|
434
478
|
- lib
|
@@ -443,12 +487,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
443
487
|
- !ruby/object:Gem::Version
|
444
488
|
version: 1.3.1
|
445
489
|
requirements: []
|
446
|
-
|
447
|
-
|
448
|
-
signing_key:
|
490
|
+
rubygems_version: 3.1.3
|
491
|
+
signing_key:
|
449
492
|
specification_version: 4
|
450
493
|
summary: Kafka libraries for Ruby.
|
451
494
|
test_files:
|
495
|
+
- spec/active_record_batch_consumer_spec.rb
|
496
|
+
- spec/active_record_consume/batch_slicer_spec.rb
|
497
|
+
- spec/active_record_consume/schema_model_converter_spec.rb
|
452
498
|
- spec/active_record_consumer_spec.rb
|
453
499
|
- spec/active_record_producer_spec.rb
|
454
500
|
- spec/backends/base_spec.rb
|
@@ -460,10 +506,13 @@ test_files:
|
|
460
506
|
- spec/config/configuration_spec.rb
|
461
507
|
- spec/consumer_spec.rb
|
462
508
|
- spec/deimos_spec.rb
|
509
|
+
- spec/generators/active_record_generator_spec.rb
|
463
510
|
- spec/handlers/my_batch_consumer.rb
|
464
511
|
- spec/handlers/my_consumer.rb
|
512
|
+
- spec/kafka_listener_spec.rb
|
465
513
|
- spec/kafka_source_spec.rb
|
466
514
|
- spec/kafka_topic_info_spec.rb
|
515
|
+
- spec/message_spec.rb
|
467
516
|
- spec/phobos.bad_db.yml
|
468
517
|
- spec/phobos.yml
|
469
518
|
- spec/producer_spec.rb
|
@@ -473,18 +522,26 @@ test_files:
|
|
473
522
|
- spec/schema_backends/avro_schema_registry_spec.rb
|
474
523
|
- spec/schema_backends/avro_validation_spec.rb
|
475
524
|
- spec/schema_backends/base_spec.rb
|
525
|
+
- spec/schemas/com/my-namespace/Generated.avsc
|
526
|
+
- spec/schemas/com/my-namespace/MyNestedSchema.avsc
|
476
527
|
- spec/schemas/com/my-namespace/MySchema-key.avsc
|
477
528
|
- spec/schemas/com/my-namespace/MySchema.avsc
|
529
|
+
- spec/schemas/com/my-namespace/MySchemaCompound-key.avsc
|
478
530
|
- spec/schemas/com/my-namespace/MySchemaWithBooleans.avsc
|
479
531
|
- spec/schemas/com/my-namespace/MySchemaWithDateTimes.avsc
|
480
532
|
- spec/schemas/com/my-namespace/MySchemaWithId.avsc
|
481
533
|
- spec/schemas/com/my-namespace/MySchemaWithUniqueId.avsc
|
534
|
+
- spec/schemas/com/my-namespace/Wibble.avsc
|
482
535
|
- spec/schemas/com/my-namespace/Widget.avsc
|
483
536
|
- spec/schemas/com/my-namespace/WidgetTheSecond.avsc
|
537
|
+
- spec/schemas/com/my-namespace/request/Index.avsc
|
538
|
+
- spec/schemas/com/my-namespace/request/UpdateRequest.avsc
|
539
|
+
- spec/schemas/com/my-namespace/response/Index.avsc
|
540
|
+
- spec/schemas/com/my-namespace/response/UpdateResponse.avsc
|
484
541
|
- spec/spec_helper.rb
|
485
542
|
- spec/utils/db_poller_spec.rb
|
486
543
|
- spec/utils/db_producer_spec.rb
|
487
|
-
- spec/utils/
|
544
|
+
- spec/utils/deadlock_retry_spec.rb
|
488
545
|
- spec/utils/lag_reporter_spec.rb
|
489
546
|
- spec/utils/platform_schema_validation_spec.rb
|
490
|
-
- spec/utils/
|
547
|
+
- spec/utils/schema_controller_mixin_spec.rb
|
data/lib/deimos/base_consumer.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Deimos
|
4
|
-
# Shared methods for Kafka Consumers
|
5
|
-
class BaseConsumer
|
6
|
-
include SharedConfig
|
7
|
-
|
8
|
-
class << self
|
9
|
-
# @return [Deimos::SchemaBackends::Base]
|
10
|
-
def decoder
|
11
|
-
@decoder ||= Deimos.schema_backend(schema: config[:schema],
|
12
|
-
namespace: config[:namespace])
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [Deimos::SchemaBackends::Base]
|
16
|
-
def key_decoder
|
17
|
-
@key_decoder ||= Deimos.schema_backend(schema: config[:key_schema],
|
18
|
-
namespace: config[:namespace])
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Helper method to decode an encoded key.
|
23
|
-
# @param key [String]
|
24
|
-
# @return [Object] the decoded key.
|
25
|
-
def decode_key(key)
|
26
|
-
return nil if key.nil?
|
27
|
-
|
28
|
-
config = self.class.config
|
29
|
-
unless config[:key_configured]
|
30
|
-
raise 'No key config given - if you are not decoding keys, please use '\
|
31
|
-
'`key_config plain: true`'
|
32
|
-
end
|
33
|
-
|
34
|
-
if config[:key_field]
|
35
|
-
self.class.decoder.decode_key(key, config[:key_field])
|
36
|
-
elsif config[:key_schema]
|
37
|
-
self.class.key_decoder.decode(key, schema: config[:key_schema])
|
38
|
-
else # no encoding
|
39
|
-
key
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def _with_span
|
46
|
-
@span = Deimos.config.tracer&.start(
|
47
|
-
'deimos-consumer',
|
48
|
-
resource: self.class.name.gsub('::', '-')
|
49
|
-
)
|
50
|
-
yield
|
51
|
-
ensure
|
52
|
-
Deimos.config.tracer&.finish(@span)
|
53
|
-
end
|
54
|
-
|
55
|
-
def _report_time_delayed(payload, metadata)
|
56
|
-
return if payload.nil? || payload['timestamp'].blank?
|
57
|
-
|
58
|
-
begin
|
59
|
-
time_delayed = Time.now.in_time_zone - payload['timestamp'].to_datetime
|
60
|
-
rescue ArgumentError
|
61
|
-
Deimos.config.logger.info(
|
62
|
-
message: "Error parsing timestamp! #{payload['timestamp']}"
|
63
|
-
)
|
64
|
-
return
|
65
|
-
end
|
66
|
-
Deimos.config.metrics&.histogram('handler', time_delayed, tags: %W(
|
67
|
-
time:time_delayed
|
68
|
-
topic:#{metadata[:topic]}
|
69
|
-
))
|
70
|
-
end
|
71
|
-
|
72
|
-
# Overrideable method to determine if a given error should be considered
|
73
|
-
# "fatal" and always be reraised.
|
74
|
-
# @param error [Exception]
|
75
|
-
# @param payload [Hash]
|
76
|
-
# @param metadata [Hash]
|
77
|
-
# @return [Boolean]
|
78
|
-
def fatal_error?(_error, _payload, _metadata)
|
79
|
-
false
|
80
|
-
end
|
81
|
-
|
82
|
-
# @param exception [Exception]
|
83
|
-
# @param payload [Hash]
|
84
|
-
# @param metadata [Hash]
|
85
|
-
def _handle_error(exception, payload, metadata)
|
86
|
-
Deimos.config.tracer&.set_error(@span, exception)
|
87
|
-
|
88
|
-
raise if Deimos.config.consumers.reraise_errors ||
|
89
|
-
Deimos.config.consumers.fatal_error&.call(exception, payload, metadata) ||
|
90
|
-
fatal_error?(exception, payload, metadata)
|
91
|
-
end
|
92
|
-
|
93
|
-
# @param _time_taken [Float]
|
94
|
-
# @param _payload [Hash]
|
95
|
-
# @param _metadata [Hash]
|
96
|
-
def _handle_success(_time_taken, _payload, _metadata)
|
97
|
-
raise NotImplementedError
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
@@ -1,124 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# rubocop:disable Lint/RescueException
|
4
|
-
module Deimos
|
5
|
-
module Utils
|
6
|
-
# Mostly copied from Phobos::Executor. We should DRY this up by putting in a
|
7
|
-
# PR to make it more generic. Might even make sense to move to a separate
|
8
|
-
# gem.
|
9
|
-
class Executor
|
10
|
-
# @return [Array<#start, #stop, #id>]
|
11
|
-
attr_accessor :runners
|
12
|
-
|
13
|
-
# @param runners [Array<#start, #stop, #id>] A list of objects that can be
|
14
|
-
# started or stopped.
|
15
|
-
# @param logger [Logger]
|
16
|
-
# @param sleep_seconds [Integer] Use a fixed time to sleep between
|
17
|
-
# failed runs instead of using an exponential backoff.
|
18
|
-
def initialize(runners, sleep_seconds: nil, logger: Logger.new(STDOUT))
|
19
|
-
@threads = Concurrent::Array.new
|
20
|
-
@runners = runners
|
21
|
-
@logger = logger
|
22
|
-
@sleep_seconds = sleep_seconds
|
23
|
-
end
|
24
|
-
|
25
|
-
# Start the executor.
|
26
|
-
def start
|
27
|
-
@logger.info('Starting executor')
|
28
|
-
@signal_to_stop = false
|
29
|
-
@threads.clear
|
30
|
-
@thread_pool = Concurrent::FixedThreadPool.new(@runners.size)
|
31
|
-
|
32
|
-
@runners.each do |runner|
|
33
|
-
@thread_pool.post do
|
34
|
-
thread = Thread.current
|
35
|
-
thread.abort_on_exception = true
|
36
|
-
@threads << thread
|
37
|
-
run_object(runner)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
true
|
42
|
-
end
|
43
|
-
|
44
|
-
# Stop the executor.
|
45
|
-
def stop
|
46
|
-
return if @signal_to_stop
|
47
|
-
|
48
|
-
@logger.info('Stopping executor')
|
49
|
-
@signal_to_stop = true
|
50
|
-
@runners.each(&:stop)
|
51
|
-
@threads.select(&:alive?).each do |thread|
|
52
|
-
begin
|
53
|
-
thread.wakeup
|
54
|
-
rescue StandardError
|
55
|
-
nil
|
56
|
-
end
|
57
|
-
end
|
58
|
-
@thread_pool&.shutdown
|
59
|
-
@thread_pool&.wait_for_termination
|
60
|
-
@logger.info('Executor stopped')
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
# @param exception [Throwable]
|
66
|
-
# @return [Hash]
|
67
|
-
def error_metadata(exception)
|
68
|
-
{
|
69
|
-
exception_class: exception.class.name,
|
70
|
-
exception_message: exception.message,
|
71
|
-
backtrace: exception.backtrace
|
72
|
-
}
|
73
|
-
end
|
74
|
-
|
75
|
-
def run_object(runner)
|
76
|
-
retry_count = 0
|
77
|
-
|
78
|
-
begin
|
79
|
-
@logger.info("Running #{runner.id}")
|
80
|
-
runner.start
|
81
|
-
retry_count = 0 # success - reset retry count
|
82
|
-
rescue Exception => e
|
83
|
-
handle_crashed_runner(runner, e, retry_count)
|
84
|
-
retry_count += 1
|
85
|
-
retry unless @signal_to_stop
|
86
|
-
end
|
87
|
-
rescue Exception => e
|
88
|
-
@logger.error("Failed to run executor (#{e.message}) #{error_metadata(e)}")
|
89
|
-
raise e
|
90
|
-
end
|
91
|
-
|
92
|
-
# @return [ExponentialBackoff]
|
93
|
-
def create_exponential_backoff
|
94
|
-
min = 1
|
95
|
-
max = 60
|
96
|
-
ExponentialBackoff.new(min, max).tap do |backoff|
|
97
|
-
backoff.randomize_factor = rand
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# When "runner#start" is interrupted / crashes we assume it's
|
102
|
-
# safe to be called again
|
103
|
-
def handle_crashed_runner(runner, error, retry_count)
|
104
|
-
interval = if @sleep_seconds
|
105
|
-
@sleep_seconds
|
106
|
-
else
|
107
|
-
backoff = create_exponential_backoff
|
108
|
-
backoff.interval_at(retry_count).round(2)
|
109
|
-
end
|
110
|
-
|
111
|
-
metadata = {
|
112
|
-
listener_id: runner.id,
|
113
|
-
retry_count: retry_count,
|
114
|
-
waiting_time: interval
|
115
|
-
}.merge(error_metadata(error))
|
116
|
-
|
117
|
-
@logger.error("Runner crashed, waiting #{interval}s (#{error.message}) #{metadata}")
|
118
|
-
sleep(interval)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# rubocop:enable Lint/RescueException
|