karafka 2.0.0 → 2.1.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
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +40 -16
- data/.rspec +4 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +459 -796
- data/Gemfile +3 -2
- data/Gemfile.lock +44 -32
- data/LICENSE +1 -1
- data/README.md +22 -17
- data/bin/integrations +86 -26
- data/bin/karafka +1 -13
- data/bin/rspecs +6 -0
- data/bin/verify_license_integrity +37 -0
- data/certs/cert_chain.pem +26 -0
- data/config/{errors.yml → locales/errors.yml} +34 -6
- data/config/locales/pro_errors.yml +34 -0
- data/docker-compose.yml +4 -30
- data/karafka.gemspec +17 -10
- data/lib/active_job/karafka.rb +3 -7
- data/lib/active_job/queue_adapters/karafka_adapter.rb +7 -1
- data/lib/karafka/active_job/consumer.rb +29 -6
- data/lib/karafka/active_job/current_attributes/loading.rb +36 -0
- data/lib/karafka/active_job/current_attributes/persistence.rb +28 -0
- data/lib/karafka/active_job/current_attributes.rb +42 -0
- data/lib/karafka/active_job/dispatcher.rb +34 -3
- data/lib/karafka/active_job/job_options_contract.rb +13 -2
- data/lib/karafka/admin.rb +246 -0
- data/lib/karafka/app.rb +30 -7
- data/lib/karafka/base_consumer.rb +124 -82
- data/lib/karafka/cli/base.rb +20 -0
- data/lib/karafka/cli/console.rb +13 -8
- data/lib/karafka/cli/info.rb +3 -2
- data/lib/karafka/cli/server.rb +55 -8
- data/lib/karafka/cli/topics.rb +146 -0
- data/lib/karafka/connection/client.rb +118 -61
- data/lib/karafka/connection/consumer_group_coordinator.rb +48 -0
- data/lib/karafka/connection/listener.rb +78 -30
- data/lib/karafka/connection/listeners_batch.rb +18 -2
- data/lib/karafka/connection/rebalance_manager.rb +3 -0
- data/lib/karafka/contracts/config.rb +1 -1
- data/lib/karafka/contracts/consumer_group.rb +22 -9
- data/lib/karafka/contracts/server_cli_options.rb +71 -11
- data/lib/karafka/contracts/topic.rb +65 -0
- data/lib/karafka/contracts.rb +1 -1
- data/lib/karafka/embedded.rb +36 -0
- data/lib/karafka/errors.rb +6 -4
- data/lib/karafka/helpers/colorize.rb +6 -0
- data/lib/karafka/instrumentation/callbacks/error.rb +3 -4
- data/lib/karafka/instrumentation/callbacks/statistics.rb +14 -4
- data/lib/karafka/instrumentation/logger_listener.rb +151 -22
- data/lib/karafka/instrumentation/notifications.rb +26 -7
- data/lib/karafka/instrumentation/proctitle_listener.rb +7 -16
- data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -1
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +153 -0
- data/lib/karafka/instrumentation/vendors/datadog/{listener.rb → metrics_listener.rb} +62 -35
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +166 -0
- data/lib/karafka/licenser.rb +53 -50
- data/lib/karafka/messages/builders/batch_metadata.rb +8 -8
- data/lib/karafka/messages/builders/messages.rb +6 -2
- data/lib/karafka/messages/message.rb +14 -2
- data/lib/karafka/messages/messages.rb +5 -0
- data/lib/karafka/messages/parser.rb +14 -0
- data/lib/karafka/patches/rdkafka/bindings.rb +132 -0
- data/lib/karafka/pro/active_job/consumer.rb +10 -9
- data/lib/karafka/pro/active_job/dispatcher.rb +28 -3
- data/lib/karafka/pro/active_job/job_options_contract.rb +16 -3
- data/lib/karafka/pro/encryption/cipher.rb +58 -0
- data/lib/karafka/pro/encryption/contracts/config.rb +79 -0
- data/lib/karafka/pro/encryption/errors.rb +24 -0
- data/lib/karafka/pro/encryption/messages/middleware.rb +46 -0
- data/lib/karafka/pro/encryption/messages/parser.rb +56 -0
- data/lib/karafka/pro/encryption/setup/config.rb +48 -0
- data/lib/karafka/pro/encryption.rb +47 -0
- data/lib/karafka/pro/iterator.rb +253 -0
- data/lib/karafka/pro/loader.rb +52 -26
- data/lib/karafka/pro/performance_tracker.rb +10 -6
- data/lib/karafka/pro/processing/collapser.rb +62 -0
- data/lib/karafka/pro/processing/coordinator.rb +92 -16
- data/lib/karafka/pro/processing/filters/base.rb +61 -0
- data/lib/karafka/pro/processing/filters/delayer.rb +70 -0
- data/lib/karafka/pro/processing/filters/expirer.rb +51 -0
- data/lib/karafka/pro/processing/filters/throttler.rb +84 -0
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +52 -0
- data/lib/karafka/pro/processing/filters_applier.rb +104 -0
- data/lib/karafka/pro/processing/jobs/consume_non_blocking.rb +7 -5
- data/lib/karafka/pro/processing/jobs/revoked_non_blocking.rb +37 -0
- data/lib/karafka/pro/processing/jobs_builder.rb +22 -4
- data/lib/karafka/pro/processing/partitioner.rb +33 -24
- data/lib/karafka/pro/processing/scheduler.rb +27 -8
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +74 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +72 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +76 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +68 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +69 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom_vp.rb +58 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +37 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +79 -0
- data/lib/karafka/pro/processing/strategies/aj/mom.rb +36 -0
- data/lib/karafka/pro/processing/strategies/aj/mom_vp.rb +52 -0
- data/lib/karafka/pro/processing/strategies/base.rb +26 -0
- data/lib/karafka/pro/processing/strategies/default.rb +105 -0
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +131 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr.rb +61 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +75 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +71 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +43 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +69 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +63 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +63 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom_vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/dlq/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +104 -0
- data/lib/karafka/pro/processing/strategies/ftr/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +87 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +69 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +67 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +80 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom_vp.rb +38 -0
- data/lib/karafka/pro/processing/strategies/lrj/vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/mom/default.rb +46 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr.rb +53 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/mom/vp.rb +35 -0
- data/lib/karafka/pro/processing/strategies/vp/default.rb +104 -0
- data/lib/karafka/pro/{contracts/base.rb → processing/strategies.rb} +6 -5
- data/lib/karafka/pro/processing/strategy_selector.rb +84 -0
- data/lib/karafka/pro/processing/virtual_offset_manager.rb +147 -0
- data/lib/karafka/pro/routing/features/base.rb +24 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue/contract.rb +50 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue.rb +27 -0
- data/lib/karafka/pro/routing/{builder_extensions.rb → features/delaying/config.rb} +8 -11
- data/lib/karafka/pro/routing/features/delaying/contract.rb +38 -0
- data/lib/karafka/pro/routing/features/delaying/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/delaying.rb +29 -0
- data/lib/karafka/pro/routing/features/expiring/config.rb +27 -0
- data/lib/karafka/pro/routing/features/expiring/contract.rb +38 -0
- data/lib/karafka/pro/routing/features/expiring/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/expiring.rb +27 -0
- data/lib/karafka/pro/routing/features/filtering/config.rb +40 -0
- data/lib/karafka/pro/routing/features/filtering/contract.rb +41 -0
- data/lib/karafka/pro/routing/features/filtering/topic.rb +51 -0
- data/lib/karafka/pro/routing/features/filtering.rb +27 -0
- data/lib/karafka/pro/routing/features/long_running_job/config.rb +28 -0
- data/lib/karafka/pro/routing/features/long_running_job/contract.rb +37 -0
- data/lib/karafka/pro/routing/features/long_running_job/topic.rb +42 -0
- data/lib/karafka/pro/routing/features/long_running_job.rb +28 -0
- data/lib/karafka/pro/routing/features/throttling/config.rb +32 -0
- data/lib/karafka/pro/routing/features/throttling/contract.rb +41 -0
- data/lib/karafka/pro/routing/features/throttling/topic.rb +69 -0
- data/lib/karafka/pro/routing/features/throttling.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/contract.rb +52 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +56 -0
- data/lib/karafka/pro/routing/features/virtual_partitions.rb +27 -0
- data/lib/karafka/process.rb +23 -8
- data/lib/karafka/processing/coordinator.rb +102 -23
- data/lib/karafka/processing/coordinators_buffer.rb +5 -1
- data/lib/karafka/processing/executor.rb +51 -21
- data/lib/karafka/processing/executors_buffer.rb +10 -26
- data/lib/karafka/processing/jobs/base.rb +6 -2
- data/lib/karafka/processing/jobs/consume.rb +8 -5
- data/lib/karafka/processing/jobs/idle.rb +24 -0
- data/lib/karafka/processing/jobs_builder.rb +2 -3
- data/lib/karafka/processing/jobs_queue.rb +14 -8
- data/lib/karafka/processing/partitioner.rb +3 -1
- data/lib/karafka/processing/result.rb +14 -1
- data/lib/karafka/processing/strategies/aj_dlq_mom.rb +44 -0
- data/lib/karafka/processing/strategies/aj_mom.rb +21 -0
- data/lib/karafka/processing/strategies/base.rb +52 -0
- data/lib/karafka/processing/strategies/default.rb +142 -0
- data/lib/karafka/processing/strategies/dlq.rb +88 -0
- data/lib/karafka/processing/strategies/dlq_mom.rb +49 -0
- data/lib/karafka/processing/strategies/mom.rb +29 -0
- data/lib/karafka/processing/strategy_selector.rb +47 -0
- data/lib/karafka/processing/worker.rb +8 -3
- data/lib/karafka/railtie.rb +24 -12
- data/lib/karafka/routing/activity_manager.rb +84 -0
- data/lib/karafka/routing/builder.rb +20 -0
- data/lib/karafka/routing/consumer_group.rb +38 -4
- data/lib/karafka/routing/consumer_mapper.rb +0 -10
- data/lib/karafka/routing/features/active_job/builder.rb +33 -0
- data/lib/karafka/routing/features/active_job/config.rb +15 -0
- data/lib/karafka/routing/features/active_job/contract.rb +41 -0
- data/lib/karafka/routing/features/active_job/topic.rb +33 -0
- data/lib/karafka/routing/features/active_job.rb +13 -0
- data/lib/karafka/routing/features/base/expander.rb +53 -0
- data/lib/karafka/routing/features/base.rb +34 -0
- data/lib/karafka/routing/features/dead_letter_queue/config.rb +19 -0
- data/lib/karafka/routing/features/dead_letter_queue/contract.rb +42 -0
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +41 -0
- data/lib/karafka/routing/features/dead_letter_queue.rb +16 -0
- data/lib/karafka/routing/features/declaratives/config.rb +18 -0
- data/lib/karafka/routing/features/declaratives/contract.rb +30 -0
- data/lib/karafka/routing/features/declaratives/topic.rb +44 -0
- data/lib/karafka/routing/features/declaratives.rb +14 -0
- data/lib/karafka/routing/features/manual_offset_management/config.rb +15 -0
- data/lib/karafka/routing/features/manual_offset_management/contract.rb +24 -0
- data/lib/karafka/routing/features/manual_offset_management/topic.rb +35 -0
- data/lib/karafka/routing/features/manual_offset_management.rb +18 -0
- data/lib/karafka/routing/proxy.rb +18 -20
- data/lib/karafka/routing/router.rb +27 -2
- data/lib/karafka/routing/subscription_group.rb +43 -5
- data/lib/karafka/routing/subscription_groups_builder.rb +6 -1
- data/lib/karafka/routing/topic.rb +17 -5
- data/lib/karafka/routing/topics.rb +8 -0
- data/lib/karafka/runner.rb +1 -0
- data/lib/karafka/serialization/json/deserializer.rb +1 -0
- data/lib/karafka/server.rb +58 -28
- data/lib/karafka/setup/attributes_map.rb +344 -0
- data/lib/karafka/setup/config.rb +48 -19
- data/lib/karafka/status.rb +35 -7
- data/lib/karafka/templates/karafka.rb.erb +14 -6
- data/lib/karafka/time_trackers/base.rb +1 -6
- data/lib/karafka/time_trackers/pause.rb +49 -19
- data/lib/karafka/time_trackers/poll.rb +7 -3
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +56 -3
- data/renovate.json +6 -0
- data.tar.gz.sig +0 -0
- metadata +189 -61
- metadata.gz.sig +0 -0
- data/bin/wait_for_kafka +0 -20
- data/certs/mensfeld.pem +0 -25
- data/lib/karafka/active_job/routing/extensions.rb +0 -31
- data/lib/karafka/contracts/consumer_group_topic.rb +0 -42
- data/lib/karafka/instrumentation.rb +0 -21
- data/lib/karafka/pro/base_consumer.rb +0 -82
- data/lib/karafka/pro/contracts/consumer_group.rb +0 -34
- data/lib/karafka/pro/contracts/consumer_group_topic.rb +0 -33
- data/lib/karafka/pro/routing/topic_extensions.rb +0 -38
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Setup
|
|
5
|
+
# To simplify the overall design, in Karafka we define all the rdkafka settings in one scope
|
|
6
|
+
# under `kafka`. rdkafka though does not like when producer options are passed to the
|
|
7
|
+
# consumer configuration and issues warnings. This target map is used as a filtering layer, so
|
|
8
|
+
# only appropriate settings go to both producer and consumer
|
|
9
|
+
#
|
|
10
|
+
# It is built based on https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md
|
|
11
|
+
module AttributesMap
|
|
12
|
+
# List of rdkafka consumer accepted attributes
|
|
13
|
+
CONSUMER = %i[
|
|
14
|
+
allow.auto.create.topics
|
|
15
|
+
api.version.fallback.ms
|
|
16
|
+
api.version.request
|
|
17
|
+
api.version.request.timeout.ms
|
|
18
|
+
auto.commit.enable
|
|
19
|
+
auto.commit.interval.ms
|
|
20
|
+
auto.offset.reset
|
|
21
|
+
background_event_cb
|
|
22
|
+
bootstrap.servers
|
|
23
|
+
broker.address.family
|
|
24
|
+
broker.address.ttl
|
|
25
|
+
broker.version.fallback
|
|
26
|
+
builtin.features
|
|
27
|
+
check.crcs
|
|
28
|
+
client.id
|
|
29
|
+
client.rack
|
|
30
|
+
closesocket_cb
|
|
31
|
+
connect_cb
|
|
32
|
+
connections.max.idle.ms
|
|
33
|
+
consume.callback.max.messages
|
|
34
|
+
consume_cb
|
|
35
|
+
coordinator.query.interval.ms
|
|
36
|
+
debug
|
|
37
|
+
default_topic_conf
|
|
38
|
+
enable.auto.commit
|
|
39
|
+
enable.auto.offset.store
|
|
40
|
+
enable.partition.eof
|
|
41
|
+
enable.random.seed
|
|
42
|
+
enable.sasl.oauthbearer.unsecure.jwt
|
|
43
|
+
enable.ssl.certificate.verification
|
|
44
|
+
enabled_events
|
|
45
|
+
error_cb
|
|
46
|
+
fetch.error.backoff.ms
|
|
47
|
+
fetch.max.bytes
|
|
48
|
+
fetch.message.max.bytes
|
|
49
|
+
fetch.min.bytes
|
|
50
|
+
fetch.wait.max.ms
|
|
51
|
+
group.id
|
|
52
|
+
group.instance.id
|
|
53
|
+
group.protocol.type
|
|
54
|
+
heartbeat.interval.ms
|
|
55
|
+
interceptors
|
|
56
|
+
internal.termination.signal
|
|
57
|
+
isolation.level
|
|
58
|
+
log.connection.close
|
|
59
|
+
log.queue
|
|
60
|
+
log.thread.name
|
|
61
|
+
log_cb
|
|
62
|
+
log_level
|
|
63
|
+
max.in.flight
|
|
64
|
+
max.in.flight.requests.per.connection
|
|
65
|
+
max.partition.fetch.bytes
|
|
66
|
+
max.poll.interval.ms
|
|
67
|
+
message.copy.max.bytes
|
|
68
|
+
message.max.bytes
|
|
69
|
+
metadata.broker.list
|
|
70
|
+
metadata.max.age.ms
|
|
71
|
+
oauthbearer_token_refresh_cb
|
|
72
|
+
offset.store.method
|
|
73
|
+
offset.store.path
|
|
74
|
+
offset.store.sync.interval.ms
|
|
75
|
+
offset_commit_cb
|
|
76
|
+
opaque
|
|
77
|
+
open_cb
|
|
78
|
+
partition.assignment.strategy
|
|
79
|
+
plugin.library.paths
|
|
80
|
+
queued.max.messages.kbytes
|
|
81
|
+
queued.min.messages
|
|
82
|
+
rebalance_cb
|
|
83
|
+
receive.message.max.bytes
|
|
84
|
+
reconnect.backoff.jitter.ms
|
|
85
|
+
reconnect.backoff.max.ms
|
|
86
|
+
reconnect.backoff.ms
|
|
87
|
+
resolve_cb
|
|
88
|
+
sasl.kerberos.keytab
|
|
89
|
+
sasl.kerberos.kinit.cmd
|
|
90
|
+
sasl.kerberos.min.time.before.relogin
|
|
91
|
+
sasl.kerberos.principal
|
|
92
|
+
sasl.kerberos.service.name
|
|
93
|
+
sasl.mechanism
|
|
94
|
+
sasl.mechanisms
|
|
95
|
+
sasl.oauthbearer.client.id
|
|
96
|
+
sasl.oauthbearer.client.secret
|
|
97
|
+
sasl.oauthbearer.config
|
|
98
|
+
sasl.oauthbearer.extensions
|
|
99
|
+
sasl.oauthbearer.method
|
|
100
|
+
sasl.oauthbearer.scope
|
|
101
|
+
sasl.oauthbearer.token.endpoint.url
|
|
102
|
+
sasl.password
|
|
103
|
+
sasl.username
|
|
104
|
+
security.protocol
|
|
105
|
+
session.timeout.ms
|
|
106
|
+
socket.blocking.max.ms
|
|
107
|
+
socket.connection.setup.timeout.ms
|
|
108
|
+
socket.keepalive.enable
|
|
109
|
+
socket.max.fails
|
|
110
|
+
socket.nagle.disable
|
|
111
|
+
socket.receive.buffer.bytes
|
|
112
|
+
socket.send.buffer.bytes
|
|
113
|
+
socket.timeout.ms
|
|
114
|
+
socket_cb
|
|
115
|
+
ssl.ca.certificate.stores
|
|
116
|
+
ssl.ca.location
|
|
117
|
+
ssl.ca.pem
|
|
118
|
+
ssl.certificate.location
|
|
119
|
+
ssl.certificate.pem
|
|
120
|
+
ssl.certificate.verify_cb
|
|
121
|
+
ssl.cipher.suites
|
|
122
|
+
ssl.crl.location
|
|
123
|
+
ssl.curves.list
|
|
124
|
+
ssl.endpoint.identification.algorithm
|
|
125
|
+
ssl.engine.id
|
|
126
|
+
ssl.engine.location
|
|
127
|
+
ssl.key.location
|
|
128
|
+
ssl.key.password
|
|
129
|
+
ssl.key.pem
|
|
130
|
+
ssl.keystore.location
|
|
131
|
+
ssl.keystore.password
|
|
132
|
+
ssl.providers
|
|
133
|
+
ssl.sigalgs.list
|
|
134
|
+
ssl_ca
|
|
135
|
+
ssl_certificate
|
|
136
|
+
ssl_engine_callback_data
|
|
137
|
+
ssl_key
|
|
138
|
+
statistics.interval.ms
|
|
139
|
+
stats_cb
|
|
140
|
+
throttle_cb
|
|
141
|
+
topic.blacklist
|
|
142
|
+
topic.metadata.propagation.max.ms
|
|
143
|
+
topic.metadata.refresh.fast.cnt
|
|
144
|
+
topic.metadata.refresh.fast.interval.ms
|
|
145
|
+
topic.metadata.refresh.interval.ms
|
|
146
|
+
topic.metadata.refresh.sparse
|
|
147
|
+
].freeze
|
|
148
|
+
|
|
149
|
+
# List of rdkafka producer accepted attributes
|
|
150
|
+
PRODUCER = %i[
|
|
151
|
+
acks
|
|
152
|
+
api.version.fallback.ms
|
|
153
|
+
api.version.request
|
|
154
|
+
api.version.request.timeout.ms
|
|
155
|
+
background_event_cb
|
|
156
|
+
batch.num.messages
|
|
157
|
+
batch.size
|
|
158
|
+
bootstrap.servers
|
|
159
|
+
broker.address.family
|
|
160
|
+
broker.address.ttl
|
|
161
|
+
broker.version.fallback
|
|
162
|
+
builtin.features
|
|
163
|
+
client.id
|
|
164
|
+
client.rack
|
|
165
|
+
closesocket_cb
|
|
166
|
+
compression.codec
|
|
167
|
+
compression.level
|
|
168
|
+
compression.type
|
|
169
|
+
connect_cb
|
|
170
|
+
connections.max.idle.ms
|
|
171
|
+
debug
|
|
172
|
+
default_topic_conf
|
|
173
|
+
delivery.report.only.error
|
|
174
|
+
delivery.timeout.ms
|
|
175
|
+
dr_cb
|
|
176
|
+
dr_msg_cb
|
|
177
|
+
enable.gapless.guarantee
|
|
178
|
+
enable.idempotence
|
|
179
|
+
enable.random.seed
|
|
180
|
+
enable.sasl.oauthbearer.unsecure.jwt
|
|
181
|
+
enable.ssl.certificate.verification
|
|
182
|
+
enabled_events
|
|
183
|
+
error_cb
|
|
184
|
+
interceptors
|
|
185
|
+
internal.termination.signal
|
|
186
|
+
linger.ms
|
|
187
|
+
log.connection.close
|
|
188
|
+
log.queue
|
|
189
|
+
log.thread.name
|
|
190
|
+
log_cb
|
|
191
|
+
log_level
|
|
192
|
+
max.in.flight
|
|
193
|
+
max.in.flight.requests.per.connection
|
|
194
|
+
message.copy.max.bytes
|
|
195
|
+
message.max.bytes
|
|
196
|
+
message.send.max.retries
|
|
197
|
+
message.timeout.ms
|
|
198
|
+
metadata.broker.list
|
|
199
|
+
metadata.max.age.ms
|
|
200
|
+
msg_order_cmp
|
|
201
|
+
oauthbearer_token_refresh_cb
|
|
202
|
+
opaque
|
|
203
|
+
open_cb
|
|
204
|
+
partitioner
|
|
205
|
+
partitioner_cb
|
|
206
|
+
plugin.library.paths
|
|
207
|
+
produce.offset.report
|
|
208
|
+
queue.buffering.backpressure.threshold
|
|
209
|
+
queue.buffering.max.kbytes
|
|
210
|
+
queue.buffering.max.messages
|
|
211
|
+
queue.buffering.max.ms
|
|
212
|
+
queuing.strategy
|
|
213
|
+
receive.message.max.bytes
|
|
214
|
+
reconnect.backoff.jitter.ms
|
|
215
|
+
reconnect.backoff.max.ms
|
|
216
|
+
reconnect.backoff.ms
|
|
217
|
+
request.required.acks
|
|
218
|
+
request.timeout.ms
|
|
219
|
+
resolve_cb
|
|
220
|
+
retries
|
|
221
|
+
retry.backoff.ms
|
|
222
|
+
sasl.kerberos.keytab
|
|
223
|
+
sasl.kerberos.kinit.cmd
|
|
224
|
+
sasl.kerberos.min.time.before.relogin
|
|
225
|
+
sasl.kerberos.principal
|
|
226
|
+
sasl.kerberos.service.name
|
|
227
|
+
sasl.mechanism
|
|
228
|
+
sasl.mechanisms
|
|
229
|
+
sasl.oauthbearer.client.id
|
|
230
|
+
sasl.oauthbearer.client.secret
|
|
231
|
+
sasl.oauthbearer.config
|
|
232
|
+
sasl.oauthbearer.extensions
|
|
233
|
+
sasl.oauthbearer.method
|
|
234
|
+
sasl.oauthbearer.scope
|
|
235
|
+
sasl.oauthbearer.token.endpoint.url
|
|
236
|
+
sasl.password
|
|
237
|
+
sasl.username
|
|
238
|
+
security.protocol
|
|
239
|
+
socket.blocking.max.ms
|
|
240
|
+
socket.connection.setup.timeout.ms
|
|
241
|
+
socket.keepalive.enable
|
|
242
|
+
socket.max.fails
|
|
243
|
+
socket.nagle.disable
|
|
244
|
+
socket.receive.buffer.bytes
|
|
245
|
+
socket.send.buffer.bytes
|
|
246
|
+
socket.timeout.ms
|
|
247
|
+
socket_cb
|
|
248
|
+
ssl.ca.certificate.stores
|
|
249
|
+
ssl.ca.location
|
|
250
|
+
ssl.ca.pem
|
|
251
|
+
ssl.certificate.location
|
|
252
|
+
ssl.certificate.pem
|
|
253
|
+
ssl.certificate.verify_cb
|
|
254
|
+
ssl.cipher.suites
|
|
255
|
+
ssl.crl.location
|
|
256
|
+
ssl.curves.list
|
|
257
|
+
ssl.endpoint.identification.algorithm
|
|
258
|
+
ssl.engine.id
|
|
259
|
+
ssl.engine.location
|
|
260
|
+
ssl.key.location
|
|
261
|
+
ssl.key.password
|
|
262
|
+
ssl.key.pem
|
|
263
|
+
ssl.keystore.location
|
|
264
|
+
ssl.keystore.password
|
|
265
|
+
ssl.providers
|
|
266
|
+
ssl.sigalgs.list
|
|
267
|
+
ssl_ca
|
|
268
|
+
ssl_certificate
|
|
269
|
+
ssl_engine_callback_data
|
|
270
|
+
ssl_key
|
|
271
|
+
statistics.interval.ms
|
|
272
|
+
stats_cb
|
|
273
|
+
sticky.partitioning.linger.ms
|
|
274
|
+
throttle_cb
|
|
275
|
+
topic.blacklist
|
|
276
|
+
topic.metadata.propagation.max.ms
|
|
277
|
+
topic.metadata.refresh.fast.cnt
|
|
278
|
+
topic.metadata.refresh.fast.interval.ms
|
|
279
|
+
topic.metadata.refresh.interval.ms
|
|
280
|
+
topic.metadata.refresh.sparse
|
|
281
|
+
transaction.timeout.ms
|
|
282
|
+
transactional.id
|
|
283
|
+
].freeze
|
|
284
|
+
|
|
285
|
+
# Location of the file with rdkafka settings list
|
|
286
|
+
SOURCE = 'https://raw.githubusercontent.com/edenhill/librdkafka/master/CONFIGURATION.md'
|
|
287
|
+
|
|
288
|
+
private_constant :SOURCE
|
|
289
|
+
|
|
290
|
+
class << self
|
|
291
|
+
# Filter the provided settings leaving only the once applicable to the consumer
|
|
292
|
+
# @param kafka_settings [Hash] all kafka settings
|
|
293
|
+
# @return [Hash] settings applicable to the consumer
|
|
294
|
+
def consumer(kafka_settings)
|
|
295
|
+
kafka_settings.slice(*CONSUMER)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Filter the provided settings leaving only the once applicable to the producer
|
|
299
|
+
# @param kafka_settings [Hash] all kafka settings
|
|
300
|
+
# @return [Hash] settings applicable to the producer
|
|
301
|
+
def producer(kafka_settings)
|
|
302
|
+
kafka_settings.slice(*PRODUCER)
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# @private
|
|
306
|
+
# @return [Hash<Symbol, Array<Symbol>>] hash with consumer and producer attributes list
|
|
307
|
+
# that is sorted.
|
|
308
|
+
# @note This method should not be used directly. It is only used to generate appropriate
|
|
309
|
+
# options list in case it would change
|
|
310
|
+
def generate
|
|
311
|
+
# Not used anywhere else, hence required here
|
|
312
|
+
require 'open-uri'
|
|
313
|
+
|
|
314
|
+
attributes = { consumer: Set.new, producer: Set.new }
|
|
315
|
+
|
|
316
|
+
::URI.parse(SOURCE).open.readlines.each do |line|
|
|
317
|
+
next unless line.include?('|')
|
|
318
|
+
|
|
319
|
+
attribute, attribute_type = line.split('|').map(&:strip)
|
|
320
|
+
|
|
321
|
+
case attribute_type
|
|
322
|
+
when 'C'
|
|
323
|
+
attributes[:consumer] << attribute
|
|
324
|
+
when 'P'
|
|
325
|
+
attributes[:producer] << attribute
|
|
326
|
+
when '*'
|
|
327
|
+
attributes[:consumer] << attribute
|
|
328
|
+
attributes[:producer] << attribute
|
|
329
|
+
else
|
|
330
|
+
next
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# This can be removed when 0.13 librdkafka is released
|
|
335
|
+
attributes[:producer].delete_if { |val| val == 'allow.auto.create.topics' }
|
|
336
|
+
|
|
337
|
+
attributes.transform_values!(&:sort)
|
|
338
|
+
attributes.each_value { |vals| vals.map!(&:to_sym) }
|
|
339
|
+
attributes
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
data/lib/karafka/setup/config.rb
CHANGED
|
@@ -16,11 +16,19 @@ module Karafka
|
|
|
16
16
|
|
|
17
17
|
# Defaults for kafka settings, that will be overwritten only if not present already
|
|
18
18
|
KAFKA_DEFAULTS = {
|
|
19
|
-
|
|
19
|
+
# We emit the statistics by default, so all the instrumentation and web-ui work out of
|
|
20
|
+
# the box, without requiring users to take any extra actions aside from enabling.
|
|
21
|
+
'statistics.interval.ms': 5_000,
|
|
22
|
+
'client.software.name': 'karafka',
|
|
23
|
+
'client.software.version': [
|
|
24
|
+
"v#{Karafka::VERSION}",
|
|
25
|
+
"rdkafka-ruby-v#{Rdkafka::VERSION}",
|
|
26
|
+
"librdkafka-v#{Rdkafka::LIBRDKAFKA_VERSION}"
|
|
27
|
+
].join('-')
|
|
20
28
|
}.freeze
|
|
21
29
|
|
|
22
30
|
# Contains settings that should not be used in production but make life easier in dev
|
|
23
|
-
|
|
31
|
+
KAFKA_DEV_DEFAULTS = {
|
|
24
32
|
# Will create non-existing topics automatically.
|
|
25
33
|
# Note that the broker needs to be configured with `auto.create.topics.enable=true`
|
|
26
34
|
# While it is not recommended in prod, it simplifies work in dev
|
|
@@ -32,7 +40,7 @@ module Karafka
|
|
|
32
40
|
'topic.metadata.refresh.interval.ms': 5_000
|
|
33
41
|
}.freeze
|
|
34
42
|
|
|
35
|
-
private_constant :KAFKA_DEFAULTS, :
|
|
43
|
+
private_constant :KAFKA_DEFAULTS, :KAFKA_DEV_DEFAULTS
|
|
36
44
|
|
|
37
45
|
# Available settings
|
|
38
46
|
|
|
@@ -68,8 +76,6 @@ module Karafka
|
|
|
68
76
|
# option [String] should we start with the earliest possible offset or latest
|
|
69
77
|
# This will set the `auto.offset.reset` value unless present in the kafka scope
|
|
70
78
|
setting :initial_offset, default: 'earliest'
|
|
71
|
-
# option [Boolean] should we leave offset management to the user
|
|
72
|
-
setting :manual_offset_management, default: false
|
|
73
79
|
# options max_messages [Integer] how many messages do we want to fetch from Kafka in one go
|
|
74
80
|
setting :max_messages, default: 100
|
|
75
81
|
# option [Integer] number of milliseconds we can wait while fetching data
|
|
@@ -80,15 +86,20 @@ module Karafka
|
|
|
80
86
|
setting :shutdown_timeout, default: 60_000
|
|
81
87
|
# option [Integer] number of threads in which we want to do parallel processing
|
|
82
88
|
setting :concurrency, default: 5
|
|
83
|
-
# option [Integer] how long should we wait upon processing error
|
|
89
|
+
# option [Integer] how long should we wait upon processing error (milliseconds)
|
|
84
90
|
setting :pause_timeout, default: 1_000
|
|
85
|
-
# option [Integer] what is the max timeout in case of an exponential backoff
|
|
91
|
+
# option [Integer] what is the max timeout in case of an exponential backoff (milliseconds)
|
|
86
92
|
setting :pause_max_timeout, default: 30_000
|
|
87
93
|
# option [Boolean] should we use exponential backoff
|
|
88
94
|
setting :pause_with_exponential_backoff, default: true
|
|
89
95
|
# option [::WaterDrop::Producer, nil]
|
|
90
96
|
# Unless configured, will be created once Karafka is configured based on user Karafka setup
|
|
91
97
|
setting :producer, default: nil
|
|
98
|
+
# option [Boolean] when set to true, Karafka will ensure that the routing topic naming
|
|
99
|
+
# convention is strict
|
|
100
|
+
# Disabling this may be needed in scenarios where we do not have control over topics names
|
|
101
|
+
# and/or we work with existing systems where we cannot change topics names.
|
|
102
|
+
setting :strict_topics_namespacing, default: true
|
|
92
103
|
|
|
93
104
|
# rdkafka default options
|
|
94
105
|
# @see https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md
|
|
@@ -109,6 +120,10 @@ module Karafka
|
|
|
109
120
|
# option subscription_groups_builder [Routing::SubscriptionGroupsBuilder] subscription
|
|
110
121
|
# group builder
|
|
111
122
|
setting :subscription_groups_builder, default: Routing::SubscriptionGroupsBuilder.new
|
|
123
|
+
|
|
124
|
+
# Internally assigned list of limits on routings active for the current process
|
|
125
|
+
# This can be altered by the CLI command
|
|
126
|
+
setting :activity_manager, default: Routing::ActivityManager.new
|
|
112
127
|
end
|
|
113
128
|
|
|
114
129
|
setting :processing do
|
|
@@ -120,6 +135,14 @@ module Karafka
|
|
|
120
135
|
setting :coordinator_class, default: Processing::Coordinator
|
|
121
136
|
# option partitioner_class [Class] partitioner we use against a batch of data
|
|
122
137
|
setting :partitioner_class, default: Processing::Partitioner
|
|
138
|
+
# option strategy_selector [Object] processing strategy selector to be used
|
|
139
|
+
setting :strategy_selector, default: Processing::StrategySelector.new
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Things related to operating on messages
|
|
143
|
+
setting :messages do
|
|
144
|
+
# Parser is used to convert raw payload prior to deserialization
|
|
145
|
+
setting :parser, default: Messages::Parser.new
|
|
123
146
|
end
|
|
124
147
|
|
|
125
148
|
# Karafka components for ActiveJob
|
|
@@ -142,17 +165,26 @@ module Karafka
|
|
|
142
165
|
# Configuring method
|
|
143
166
|
# @param block [Proc] block we want to execute with the config instance
|
|
144
167
|
def setup(&block)
|
|
168
|
+
# Will prepare and verify license if present
|
|
169
|
+
Licenser.prepare_and_verify(config.license)
|
|
170
|
+
# Will configure all the pro components
|
|
171
|
+
# This needs to happen before end user configuration as the end user may overwrite some
|
|
172
|
+
# of the pro defaults with custom components
|
|
173
|
+
Pro::Loader.pre_setup(config) if Karafka.pro?
|
|
174
|
+
|
|
145
175
|
configure(&block)
|
|
146
176
|
merge_kafka_defaults!(config)
|
|
147
177
|
|
|
148
178
|
Contracts::Config.new.validate!(config.to_h)
|
|
149
179
|
|
|
150
|
-
|
|
180
|
+
configure_components
|
|
151
181
|
|
|
152
|
-
#
|
|
153
|
-
|
|
182
|
+
# Refreshes the references that are cached that might have been changed by the config
|
|
183
|
+
::Karafka.refresh!
|
|
154
184
|
|
|
155
|
-
|
|
185
|
+
# Runs things that need to be executed after config is defined and all the components
|
|
186
|
+
# are also configured
|
|
187
|
+
Pro::Loader.post_setup(config) if Karafka.pro?
|
|
156
188
|
|
|
157
189
|
Karafka::App.initialized!
|
|
158
190
|
end
|
|
@@ -170,9 +202,12 @@ module Karafka
|
|
|
170
202
|
config.kafka[key] = value
|
|
171
203
|
end
|
|
172
204
|
|
|
205
|
+
# Use Karafka client_id as kafka client id if not set
|
|
206
|
+
config.kafka[:'client.id'] ||= config.client_id
|
|
207
|
+
|
|
173
208
|
return if Karafka::App.env.production?
|
|
174
209
|
|
|
175
|
-
|
|
210
|
+
KAFKA_DEV_DEFAULTS.each do |key, value|
|
|
176
211
|
next if config.kafka.key?(key)
|
|
177
212
|
|
|
178
213
|
config.kafka[key] = value
|
|
@@ -185,15 +220,9 @@ module Karafka
|
|
|
185
220
|
config.producer ||= ::WaterDrop::Producer.new do |producer_config|
|
|
186
221
|
# In some cases WaterDrop updates the config and we don't want our consumer config to
|
|
187
222
|
# be polluted by those updates, that's why we copy
|
|
188
|
-
producer_config.kafka = config.kafka.dup
|
|
223
|
+
producer_config.kafka = AttributesMap.producer(config.kafka.dup)
|
|
189
224
|
producer_config.logger = config.logger
|
|
190
225
|
end
|
|
191
|
-
|
|
192
|
-
return unless Karafka.pro?
|
|
193
|
-
|
|
194
|
-
# Runs the pro loader that includes all the pro components
|
|
195
|
-
require 'karafka/pro/loader'
|
|
196
|
-
Pro::Loader.setup(config)
|
|
197
226
|
end
|
|
198
227
|
end
|
|
199
228
|
end
|
data/lib/karafka/status.rb
CHANGED
|
@@ -8,30 +8,58 @@ module Karafka
|
|
|
8
8
|
initializing: :initialize!,
|
|
9
9
|
initialized: :initialized!,
|
|
10
10
|
running: :run!,
|
|
11
|
+
# will no longer pickup any work, but current work will be finished
|
|
12
|
+
quieting: :quiet!,
|
|
13
|
+
# no work is happening but we keep process with the assignments running
|
|
14
|
+
quiet: :quieted!,
|
|
15
|
+
# shutdown started
|
|
11
16
|
stopping: :stop!,
|
|
12
|
-
|
|
17
|
+
# all things are done and most of the things except critical are closed
|
|
18
|
+
stopped: :stopped!,
|
|
19
|
+
# immediately after this process exists
|
|
20
|
+
terminated: :terminate!
|
|
13
21
|
}.freeze
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
# Mutex to ensure that state transitions are thread-safe
|
|
24
|
+
MUTEX = Mutex.new
|
|
25
|
+
|
|
26
|
+
private_constant :MUTEX
|
|
16
27
|
|
|
17
28
|
# By default we are in the initializing state
|
|
18
29
|
def initialize
|
|
19
30
|
initialize!
|
|
20
31
|
end
|
|
21
32
|
|
|
33
|
+
# @return [String] stringified current app status
|
|
34
|
+
def to_s
|
|
35
|
+
@status.to_s
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Resets the status state
|
|
39
|
+
# This is used mostly in the integration suite
|
|
40
|
+
def reset!
|
|
41
|
+
@status = :initializing
|
|
42
|
+
end
|
|
43
|
+
|
|
22
44
|
STATES.each do |state, transition|
|
|
23
45
|
define_method :"#{state}?" do
|
|
24
46
|
@status == state
|
|
25
47
|
end
|
|
26
48
|
|
|
27
49
|
define_method transition do
|
|
28
|
-
|
|
50
|
+
MUTEX.synchronize do
|
|
51
|
+
# Do not allow reverse state transitions (we always go one way) or transition to the same
|
|
52
|
+
# state as currently
|
|
53
|
+
return if @status && STATES.keys.index(state) <= STATES.keys.index(@status)
|
|
54
|
+
|
|
55
|
+
@status = state
|
|
29
56
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
57
|
+
# Skip on creation (initializing)
|
|
58
|
+
# We skip as during this state we do not have yet a monitor
|
|
59
|
+
return if initializing?
|
|
33
60
|
|
|
34
|
-
|
|
61
|
+
Karafka.monitor.instrument("app.#{state}")
|
|
62
|
+
end
|
|
35
63
|
end
|
|
36
64
|
end
|
|
37
65
|
end
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
<% unless rails? -%>
|
|
2
3
|
|
|
3
|
-
<% if rails? -%>
|
|
4
|
-
require ::File.expand_path('../config/environment', __FILE__)
|
|
5
|
-
<% else -%>
|
|
6
4
|
# This file is auto-generated during the install process.
|
|
7
5
|
# If by any chance you've wanted a setup for Rails app, either run the `karafka:install`
|
|
8
6
|
# command again or refer to the install templates available in the source codes
|
|
9
7
|
|
|
10
|
-
ENV['
|
|
11
|
-
ENV['KARAFKA_ENV'] ||= ENV['RACK_ENV']
|
|
8
|
+
ENV['KARAFKA_ENV'] ||= 'development'
|
|
12
9
|
Bundler.require(:default, ENV['KARAFKA_ENV'])
|
|
13
10
|
|
|
14
11
|
# Zeitwerk custom loader for loading the app components before the whole
|
|
@@ -43,13 +40,24 @@ class KarafkaApp < Karafka::App
|
|
|
43
40
|
Karafka.monitor.subscribe(Karafka::Instrumentation::LoggerListener.new)
|
|
44
41
|
# Karafka.monitor.subscribe(Karafka::Instrumentation::ProctitleListener.new)
|
|
45
42
|
|
|
43
|
+
# This logger prints the producer development info using the Karafka logger.
|
|
44
|
+
# It is similar to the consumer logger listener but producer oriented.
|
|
45
|
+
Karafka.producer.monitor.subscribe(
|
|
46
|
+
WaterDrop::Instrumentation::LoggerListener.new(Karafka.logger)
|
|
47
|
+
)
|
|
48
|
+
|
|
46
49
|
routes.draw do
|
|
47
50
|
<% if rails? -%>
|
|
48
51
|
# Uncomment this if you use Karafka with ActiveJob
|
|
49
|
-
# You
|
|
52
|
+
# You need to define the topic per each queue name you use
|
|
50
53
|
# active_job_topic :default
|
|
51
54
|
<% end -%>
|
|
52
55
|
topic :example do
|
|
56
|
+
# Uncomment this if you want Karafka to manage your topics configuration
|
|
57
|
+
# Managing topics configuration via routing will allow you to ensure config consistency
|
|
58
|
+
# across multiple environments
|
|
59
|
+
#
|
|
60
|
+
# config(partitions: 2, 'cleanup.policy': 'compact')
|
|
53
61
|
consumer ExampleConsumer
|
|
54
62
|
end
|
|
55
63
|
end
|
|
@@ -8,12 +8,7 @@ module Karafka
|
|
|
8
8
|
module TimeTrackers
|
|
9
9
|
# Base class for all the time-trackers.
|
|
10
10
|
class Base
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
# @return [Float] current time in milliseconds
|
|
14
|
-
def now
|
|
15
|
-
::Process.clock_gettime(::Process::CLOCK_MONOTONIC) * 1000
|
|
16
|
-
end
|
|
11
|
+
include ::Karafka::Core::Helpers::Time
|
|
17
12
|
end
|
|
18
13
|
end
|
|
19
14
|
end
|