karafka 1.2.8 → 1.4.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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.coditsu/ci.yml +3 -0
  5. data/.console_irbrc +1 -3
  6. data/.diffend.yml +3 -0
  7. data/.github/FUNDING.yml +3 -0
  8. data/.github/ISSUE_TEMPLATE/bug_report.md +50 -0
  9. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  10. data/.github/workflows/ci.yml +52 -0
  11. data/.gitignore +1 -0
  12. data/.ruby-version +1 -1
  13. data/CHANGELOG.md +134 -14
  14. data/CODE_OF_CONDUCT.md +1 -1
  15. data/CONTRIBUTING.md +1 -1
  16. data/Gemfile +4 -5
  17. data/Gemfile.lock +92 -81
  18. data/README.md +9 -12
  19. data/bin/karafka +1 -1
  20. data/certs/mensfeld.pem +25 -0
  21. data/config/errors.yml +38 -5
  22. data/docker-compose.yml +17 -0
  23. data/karafka.gemspec +18 -17
  24. data/lib/karafka.rb +10 -16
  25. data/lib/karafka/app.rb +14 -6
  26. data/lib/karafka/attributes_map.rb +5 -10
  27. data/lib/karafka/base_consumer.rb +19 -30
  28. data/lib/karafka/base_responder.rb +45 -27
  29. data/lib/karafka/cli.rb +2 -2
  30. data/lib/karafka/cli/console.rb +11 -9
  31. data/lib/karafka/cli/flow.rb +9 -7
  32. data/lib/karafka/cli/info.rb +4 -2
  33. data/lib/karafka/cli/install.rb +30 -6
  34. data/lib/karafka/cli/server.rb +11 -6
  35. data/lib/karafka/code_reloader.rb +67 -0
  36. data/lib/karafka/connection/api_adapter.rb +22 -9
  37. data/lib/karafka/connection/batch_delegator.rb +55 -0
  38. data/lib/karafka/connection/builder.rb +5 -3
  39. data/lib/karafka/connection/client.rb +31 -31
  40. data/lib/karafka/connection/listener.rb +26 -15
  41. data/lib/karafka/connection/message_delegator.rb +36 -0
  42. data/lib/karafka/consumers/batch_metadata.rb +10 -0
  43. data/lib/karafka/consumers/callbacks.rb +32 -15
  44. data/lib/karafka/consumers/includer.rb +31 -18
  45. data/lib/karafka/consumers/responders.rb +2 -2
  46. data/lib/karafka/contracts.rb +10 -0
  47. data/lib/karafka/contracts/config.rb +21 -0
  48. data/lib/karafka/contracts/consumer_group.rb +206 -0
  49. data/lib/karafka/contracts/consumer_group_topic.rb +19 -0
  50. data/lib/karafka/contracts/responder_usage.rb +54 -0
  51. data/lib/karafka/contracts/server_cli_options.rb +31 -0
  52. data/lib/karafka/errors.rb +17 -16
  53. data/lib/karafka/fetcher.rb +28 -30
  54. data/lib/karafka/helpers/class_matcher.rb +12 -2
  55. data/lib/karafka/helpers/config_retriever.rb +1 -1
  56. data/lib/karafka/helpers/inflector.rb +26 -0
  57. data/lib/karafka/helpers/multi_delegator.rb +0 -1
  58. data/lib/karafka/instrumentation/logger.rb +9 -6
  59. data/lib/karafka/instrumentation/monitor.rb +15 -9
  60. data/lib/karafka/instrumentation/proctitle_listener.rb +36 -0
  61. data/lib/karafka/instrumentation/stdout_listener.rb +140 -0
  62. data/lib/karafka/params/batch_metadata.rb +26 -0
  63. data/lib/karafka/params/builders/batch_metadata.rb +30 -0
  64. data/lib/karafka/params/builders/params.rb +38 -0
  65. data/lib/karafka/params/builders/params_batch.rb +25 -0
  66. data/lib/karafka/params/metadata.rb +20 -0
  67. data/lib/karafka/params/params.rb +54 -0
  68. data/lib/karafka/params/params_batch.rb +35 -21
  69. data/lib/karafka/patches/ruby_kafka.rb +21 -8
  70. data/lib/karafka/persistence/client.rb +15 -11
  71. data/lib/karafka/persistence/{consumer.rb → consumers.rb} +20 -13
  72. data/lib/karafka/persistence/topics.rb +48 -0
  73. data/lib/karafka/process.rb +0 -2
  74. data/lib/karafka/responders/builder.rb +1 -1
  75. data/lib/karafka/responders/topic.rb +6 -8
  76. data/lib/karafka/routing/builder.rb +36 -8
  77. data/lib/karafka/routing/consumer_group.rb +1 -1
  78. data/lib/karafka/routing/consumer_mapper.rb +9 -9
  79. data/lib/karafka/routing/proxy.rb +10 -1
  80. data/lib/karafka/routing/topic.rb +5 -3
  81. data/lib/karafka/routing/topic_mapper.rb +16 -18
  82. data/lib/karafka/serialization/json/deserializer.rb +27 -0
  83. data/lib/karafka/serialization/json/serializer.rb +31 -0
  84. data/lib/karafka/server.rb +29 -28
  85. data/lib/karafka/setup/config.rb +67 -37
  86. data/lib/karafka/setup/configurators/water_drop.rb +7 -3
  87. data/lib/karafka/setup/dsl.rb +0 -1
  88. data/lib/karafka/status.rb +7 -3
  89. data/lib/karafka/templates/{application_consumer.rb.example → application_consumer.rb.erb} +2 -1
  90. data/lib/karafka/templates/{application_responder.rb.example → application_responder.rb.erb} +0 -0
  91. data/lib/karafka/templates/karafka.rb.erb +92 -0
  92. data/lib/karafka/version.rb +1 -1
  93. metadata +94 -72
  94. metadata.gz.sig +0 -0
  95. data/.travis.yml +0 -21
  96. data/lib/karafka/callbacks.rb +0 -30
  97. data/lib/karafka/callbacks/config.rb +0 -22
  98. data/lib/karafka/callbacks/dsl.rb +0 -16
  99. data/lib/karafka/connection/delegator.rb +0 -46
  100. data/lib/karafka/instrumentation/listener.rb +0 -112
  101. data/lib/karafka/loader.rb +0 -28
  102. data/lib/karafka/params/dsl.rb +0 -156
  103. data/lib/karafka/parsers/json.rb +0 -38
  104. data/lib/karafka/patches/dry_configurable.rb +0 -35
  105. data/lib/karafka/persistence/topic.rb +0 -29
  106. data/lib/karafka/schemas/config.rb +0 -24
  107. data/lib/karafka/schemas/consumer_group.rb +0 -78
  108. data/lib/karafka/schemas/consumer_group_topic.rb +0 -18
  109. data/lib/karafka/schemas/responder_usage.rb +0 -39
  110. data/lib/karafka/schemas/server_cli_options.rb +0 -43
  111. data/lib/karafka/setup/configurators/base.rb +0 -29
  112. data/lib/karafka/setup/configurators/params.rb +0 -25
  113. data/lib/karafka/templates/karafka.rb.example +0 -54
@@ -7,18 +7,22 @@ module Karafka
7
7
  # Thread.current key under which we store current thread messages consumer client
8
8
  PERSISTENCE_SCOPE = :client
9
9
 
10
- # @param client [Karafka::Connection::Client] messages consumer client of
11
- # a current thread
12
- # @return [Karafka::Connection::Client] persisted messages consumer client
13
- def self.write(client)
14
- Thread.current[PERSISTENCE_SCOPE] = client
15
- end
10
+ private_constant :PERSISTENCE_SCOPE
11
+
12
+ class << self
13
+ # @param client [Karafka::Connection::Client] messages consumer client of
14
+ # a current thread
15
+ # @return [Karafka::Connection::Client] persisted messages consumer client
16
+ def write(client)
17
+ Thread.current[PERSISTENCE_SCOPE] = client
18
+ end
16
19
 
17
- # @return [Karafka::Connection::Client] persisted messages consumer client
18
- # @raise [Karafka::Errors::MissingConsumer] raised when no thread messages consumer
19
- # client but we try to use it anyway
20
- def self.read
21
- Thread.current[PERSISTENCE_SCOPE] || raise(Errors::MissingClient)
20
+ # @return [Karafka::Connection::Client] persisted messages consumer client
21
+ # @raise [Karafka::Errors::MissingClientError] raised when no thread messages consumer
22
+ # client but we try to use it anyway
23
+ def read
24
+ Thread.current[PERSISTENCE_SCOPE] || raise(Errors::MissingClientError)
25
+ end
22
26
  end
23
27
  end
24
28
  end
@@ -7,30 +7,37 @@ module Karafka
7
7
  # Module used to provide a persistent cache across batch requests for a given
8
8
  # topic and partition to store some additional details when the persistent mode
9
9
  # for a given topic is turned on
10
- class Consumer
10
+ class Consumers
11
11
  # Thread.current scope under which we store consumers data
12
12
  PERSISTENCE_SCOPE = :consumers
13
13
 
14
+ private_constant :PERSISTENCE_SCOPE
15
+
14
16
  class << self
15
- # @return [Hash] current thread persistence scope hash with all the consumers
16
- def all
17
- # @note This does not need to be threadsafe (Hash) as it is always executed in a
18
- # current thread context
19
- Thread.current[PERSISTENCE_SCOPE] ||= Hash.new { |hash, key| hash[key] = {} }
17
+ # @return [Hash] current thread's persistence scope hash with all the consumers
18
+ def current
19
+ Thread.current[PERSISTENCE_SCOPE] ||= Concurrent::Hash.new do |hash, key|
20
+ hash[key] = Concurrent::Hash.new
21
+ end
20
22
  end
21
23
 
22
24
  # Used to build (if block given) and/or fetch a current consumer instance that will be
23
25
  # used to process messages from a given topic and partition
24
- # @return [Karafka::BaseConsumer] base consumer descendant
25
26
  # @param topic [Karafka::Routing::Topic] topic instance for which we might cache
26
27
  # @param partition [Integer] number of partition for which we want to cache
28
+ # @return [Karafka::BaseConsumer] base consumer descendant
27
29
  def fetch(topic, partition)
28
- # We always store a current instance for callback reasons
29
- if topic.persistent
30
- all[topic][partition] ||= topic.consumer.new
31
- else
32
- all[topic][partition] = topic.consumer.new
33
- end
30
+ current[topic][partition] ||= topic.consumer.new(topic)
31
+ end
32
+
33
+ # Removes all persisted instances of consumers from the consumer cache
34
+ # @note This is used to reload consumers instances when code reloading in development mode
35
+ # is present. This should not be used in production.
36
+ def clear
37
+ Thread
38
+ .list
39
+ .select { |thread| thread[PERSISTENCE_SCOPE] }
40
+ .each { |thread| thread[PERSISTENCE_SCOPE].clear }
34
41
  end
35
42
  end
36
43
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Persistence
5
+ # Local cache for routing topics
6
+ # We use it in order not to build string instances and remap incoming topic upon each
7
+ # message / message batches received
8
+ class Topics
9
+ # Thread.current scope under which we store topics data
10
+ PERSISTENCE_SCOPE = :topics
11
+
12
+ private_constant :PERSISTENCE_SCOPE
13
+
14
+ class << self
15
+ # @return [Concurrent::Hash] hash with all the topics from given groups
16
+ def current
17
+ Thread.current[PERSISTENCE_SCOPE] ||= Concurrent::Hash.new do |hash, key|
18
+ hash[key] = Concurrent::Hash.new
19
+ end
20
+ end
21
+
22
+ # @param group_id [String] group id for which we fetch a topic representation
23
+ # @param raw_topic_name [String] raw topic name (before remapping) for which we fetch a
24
+ # topic representation
25
+ # @return [Karafka::Routing::Topics] remapped topic representation that can be used further
26
+ # on when working with given parameters
27
+ def fetch(group_id, raw_topic_name)
28
+ current[group_id][raw_topic_name] ||= begin
29
+ # We map from incoming topic name, as it might be namespaced, etc.
30
+ # @see topic_mapper internal docs
31
+ mapped_topic_name = Karafka::App.config.topic_mapper.incoming(raw_topic_name)
32
+ Routing::Router.find("#{group_id}_#{mapped_topic_name}")
33
+ end
34
+ end
35
+
36
+ # Clears the whole topics cache for all the threads
37
+ # This is used for in-development code reloading as we need to get rid of all the
38
+ # preloaded and cached instances of objects to make it work
39
+ def clear
40
+ Thread
41
+ .list
42
+ .select { |thread| thread[PERSISTENCE_SCOPE] }
43
+ .each { |thread| thread[PERSISTENCE_SCOPE].clear }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -4,8 +4,6 @@ module Karafka
4
4
  # Class used to catch signals from ruby Signal class in order to manage Karafka stop
5
5
  # @note There might be only one process - this class is a singleton
6
6
  class Process
7
- include Singleton
8
-
9
7
  # Signal types that we handle
10
8
  HANDLED_SIGNALS = %i[
11
9
  SIGINT
@@ -3,7 +3,7 @@
3
3
  module Karafka
4
4
  # Responders namespace encapsulates all the internal responder implementation parts
5
5
  module Responders
6
- # Responders builder is used to finding (based on the consumer class name) a responder
6
+ # Responders builder is used for finding (based on the consumer class name) a responder
7
7
  # that match the consumer. We use it when user does not provide a responder inside routing,
8
8
  # but he still names responder with the same convention (and namespaces) as consumer
9
9
  #
@@ -7,8 +7,6 @@ module Karafka
7
7
  # Karafka::Responders::Topic.new(:topic_name, {}) #=> #<Karafka::Responders::Topic...
8
8
  # @example Define optional topic
9
9
  # Karafka::Responders::Topic.new(:topic_name, required: false)
10
- # @example Define topic that on which we want to respond multiple times
11
- # Karafka::Responders::Topic.new(:topic_name, multiple_usage: true)
12
10
  class Topic
13
11
  # Name of the topic on which we want to respond
14
12
  attr_reader :name
@@ -26,16 +24,16 @@ module Karafka
26
24
  @options.key?(:required) ? @options[:required] : true
27
25
  end
28
26
 
29
- # @return [Boolean] do we expect to use it multiple times in a single respond flow
30
- def multiple_usage?
31
- @options[:multiple_usage] || false
32
- end
33
-
34
27
  # @return [Boolean] was usage of this topic registered or not
35
28
  def registered?
36
29
  @options[:registered] == true
37
30
  end
38
31
 
32
+ # @return [Class] Class to use to serialize messages for this topic
33
+ def serializer
34
+ @options[:serializer]
35
+ end
36
+
39
37
  # @return [Boolean] do we want to use async producer. Defaults to false as the sync producer
40
38
  # is safer and introduces less problems
41
39
  def async?
@@ -46,9 +44,9 @@ module Karafka
46
44
  def to_h
47
45
  {
48
46
  name: name,
49
- multiple_usage: multiple_usage?,
50
47
  required: required?,
51
48
  registered: registered?,
49
+ serializer: serializer,
52
50
  async: async?
53
51
  }
54
52
  end
@@ -9,26 +9,39 @@ module Karafka
9
9
  # consumer NewVideosConsumer
10
10
  # end
11
11
  # end
12
- class Builder < Array
13
- include Singleton
12
+ class Builder < Concurrent::Array
13
+ # Consumer group consistency checking contract
14
+ CONTRACT = Karafka::Contracts::ConsumerGroup.new.freeze
15
+
16
+ private_constant :CONTRACT
17
+
18
+ def initialize
19
+ @draws = Concurrent::Array.new
20
+ end
14
21
 
15
22
  # Used to draw routes for Karafka
23
+ # @param block [Proc] block we will evaluate within the builder context
24
+ # @yield Evaluates provided block in a builder context so we can describe routes
25
+ # @raise [Karafka::Errors::InvalidConfigurationError] raised when configuration
26
+ # doesn't match with the config contract
16
27
  # @note After it is done drawing it will store and validate all the routes to make sure that
17
28
  # they are correct and that there are no topic/group duplications (this is forbidden)
18
- # @yield Evaluates provided block in a builder context so we can describe routes
19
29
  # @example
20
30
  # draw do
21
31
  # topic :xyz do
22
32
  # end
23
33
  # end
24
34
  def draw(&block)
35
+ @draws << block
36
+
25
37
  instance_eval(&block)
26
38
 
27
39
  each do |consumer_group|
28
40
  hashed_group = consumer_group.to_h
29
- validation_result = Karafka::Schemas::ConsumerGroup.call(hashed_group)
30
- return if validation_result.success?
31
- raise Errors::InvalidConfiguration, validation_result.errors
41
+ validation_result = CONTRACT.call(hashed_group)
42
+ next if validation_result.success?
43
+
44
+ raise Errors::InvalidConfigurationError, validation_result.errors.to_h
32
45
  end
33
46
  end
34
47
 
@@ -39,18 +52,33 @@ module Karafka
39
52
  select(&:active?)
40
53
  end
41
54
 
55
+ # Clears the builder and the draws memory
56
+ def clear
57
+ @draws.clear
58
+ super
59
+ end
60
+
61
+ # Redraws all the routes for the in-process code reloading.
62
+ # @note This won't allow registration of new topics without process restart but will trigger
63
+ # cache invalidation so all the classes, etc are re-fetched after code reload
64
+ def reload
65
+ draws = @draws.dup
66
+ clear
67
+ draws.each { |block| draw(&block) }
68
+ end
69
+
42
70
  private
43
71
 
44
72
  # Builds and saves given consumer group
45
73
  # @param group_id [String, Symbol] name for consumer group
46
- # @yield Evaluates a given block in a consumer group context
74
+ # @param block [Proc] proc that should be executed in the proxy context
47
75
  def consumer_group(group_id, &block)
48
76
  consumer_group = ConsumerGroup.new(group_id.to_s)
49
77
  self << Proxy.new(consumer_group, &block).target
50
78
  end
51
79
 
52
80
  # @param topic_name [String, Symbol] name of a topic from which we want to consumer
53
- # @yield Evaluates a given block in a topic context
81
+ # @param block [Proc] proc we want to evaluate in the topic context
54
82
  def topic(topic_name, &block)
55
83
  consumer_group(topic_name) do
56
84
  topic(topic_name, &block).tap(&:build)
@@ -29,7 +29,7 @@ module Karafka
29
29
 
30
30
  # Builds a topic representation inside of a current consumer group route
31
31
  # @param name [String, Symbol] name of topic to which we want to subscribe
32
- # @yield Evaluates a given block in a topic context
32
+ # @param block [Proc] block that we want to evaluate in the topic context
33
33
  # @return [Karafka::Routing::Topic] newly built topic instance
34
34
  def topic=(name, &block)
35
35
  topic = Topic.new(name, self)
@@ -4,29 +4,29 @@ module Karafka
4
4
  module Routing
5
5
  # Default consumer mapper that builds consumer ids based on app id and consumer group name
6
6
  # Different mapper can be used in case of preexisting consumer names or for applying
7
- # other naming conventions not compatible wiih Karafkas client_id + consumer name concept
7
+ # other naming conventions not compatible with Karafka client_id + consumer name concept
8
8
  #
9
9
  # @example Mapper for using consumer groups without a client_id prefix
10
- # module MyMapper
11
- # def self.call(raw_consumer_group_name)
10
+ # class MyMapper
11
+ # def call(raw_consumer_group_name)
12
12
  # raw_consumer_group_name
13
13
  # end
14
14
  # end
15
15
  #
16
16
  # @example Mapper for replacing "_" with "." in topic names
17
- # module MyMapper
18
- # def self.call(raw_consumer_group_name)
17
+ # class MyMapper
18
+ # def call(raw_consumer_group_name)
19
19
  # [
20
- # Dry::Inflector.new.underscore(Karafka::App.config.client_id.to_s),
20
+ # Karafka::Helpers::Inflector.map(Karafka::App.config.client_id.to_s),
21
21
  # raw_consumer_group_name
22
22
  # ].join('_').gsub('_', '.')
23
23
  # end
24
24
  # end
25
- module ConsumerMapper
25
+ class ConsumerMapper
26
26
  # @param raw_consumer_group_name [String, Symbol] string or symbolized consumer group name
27
27
  # @return [String] remapped final consumer group name
28
- def self.call(raw_consumer_group_name)
29
- client_name = Dry::Inflector.new.underscore(Karafka::App.config.client_id.to_s)
28
+ def call(raw_consumer_group_name)
29
+ client_name = Karafka::Helpers::Inflector.map(Karafka::App.config.client_id.to_s)
30
30
  "#{client_name}_#{raw_consumer_group_name}"
31
31
  end
32
32
  end
@@ -14,22 +14,31 @@ module Karafka
14
14
  !
15
15
  ].freeze
16
16
 
17
+ private_constant :IGNORED_POSTFIXES
18
+
17
19
  # @param target [Object] target object to which we proxy any DSL call
18
- # @yield Evaluates block in the proxy context
20
+ # @param block [Proc] block that we want to evaluate in the proxy context
19
21
  def initialize(target, &block)
20
22
  @target = target
21
23
  instance_eval(&block)
22
24
  end
23
25
 
24
26
  # Translates the no "=" DSL of routing into elements assignments on target
27
+ # @param method_name [Symbol] name of the missing method
28
+ # @param arguments [Array] array with it's arguments
29
+ # @param block [Proc] block provided to the method
25
30
  def method_missing(method_name, *arguments, &block)
26
31
  return super unless respond_to_missing?(method_name)
32
+
27
33
  @target.public_send(:"#{method_name}=", *arguments, &block)
28
34
  end
29
35
 
30
36
  # Tells whether or not a given element exists on the target
37
+ # @param method_name [Symbol] name of the missing method
38
+ # @param include_private [Boolean] should we include private in the check as well
31
39
  def respond_to_missing?(method_name, include_private = false)
32
40
  return false if IGNORED_POSTFIXES.any? { |postfix| method_name.to_s.end_with?(postfix) }
41
+
33
42
  @target.respond_to?(:"#{method_name}=", include_private) || super
34
43
  end
35
44
  end
@@ -7,10 +7,13 @@ module Karafka
7
7
  # It is a part of Karafka's DSL
8
8
  class Topic
9
9
  extend Helpers::ConfigRetriever
10
+ extend Forwardable
10
11
 
11
12
  attr_reader :id, :consumer_group
12
13
  attr_accessor :consumer
13
14
 
15
+ def_delegator :@consumer_group, :batch_fetching
16
+
14
17
  # @param [String, Symbol] name of a topic on which we want to listen
15
18
  # @param consumer_group [Karafka::Routing::ConsumerGroup] owning consumer group of this topic
16
19
  def initialize(name, consumer_group)
@@ -19,7 +22,7 @@ module Karafka
19
22
  @attributes = {}
20
23
  # @note We use identifier related to the consumer group that owns a topic, because from
21
24
  # Karafka 0.6 we can handle multiple Kafka instances with the same process and we can
22
- # have same topic name across mutliple Kafkas
25
+ # have same topic name across multiple Kafkas
23
26
  @id = "#{consumer_group.id}_#{@name}"
24
27
  end
25
28
 
@@ -29,12 +32,11 @@ module Karafka
29
32
  # example for Sidekiq
30
33
  def build
31
34
  Karafka::AttributesMap.topic.each { |attr| send(attr) }
32
- consumer&.topic = self
33
35
  self
34
36
  end
35
37
 
36
38
  # @return [Class, nil] Class (not an instance) of a responder that should respond from
37
- # consumer back to Kafka (usefull for piping dataflows)
39
+ # consumer back to Kafka (useful for piping data flows)
38
40
  def responder
39
41
  @responder ||= Karafka::Responders::Builder.new(consumer).build
40
42
  end
@@ -8,7 +8,7 @@ module Karafka
8
8
  # routes and responders
9
9
  #
10
10
  # @example Mapper for mapping prefixed topics
11
- # module MyMapper
11
+ # class MyMapper
12
12
  # PREFIX = "my_user_name."
13
13
  #
14
14
  # def incoming(topic)
@@ -21,7 +21,7 @@ module Karafka
21
21
  # end
22
22
  #
23
23
  # @example Mapper for replacing "." with "_" in topic names
24
- # module MyMapper
24
+ # class MyMapper
25
25
  # PREFIX = "my_user_name."
26
26
  #
27
27
  # def incoming(topic)
@@ -32,23 +32,21 @@ module Karafka
32
32
  # topic.to_s.gsub('_', '.')
33
33
  # end
34
34
  # end
35
- module TopicMapper
36
- class << self
37
- # @param topic [String, Symbol] topic
38
- # @return [String, Symbol] same topic as on input
39
- # @example
40
- # incoming('topic_name') #=> 'topic_name'
41
- def incoming(topic)
42
- topic
43
- end
35
+ class TopicMapper
36
+ # @param topic [String, Symbol] topic
37
+ # @return [String, Symbol] same topic as on input
38
+ # @example
39
+ # incoming('topic_name') #=> 'topic_name'
40
+ def incoming(topic)
41
+ topic
42
+ end
44
43
 
45
- # @param topic [String, Symbol] topic
46
- # @return [String, Symbol] same topic as on input
47
- # @example
48
- # outgoing('topic_name') #=> 'topic_name'
49
- def outgoing(topic)
50
- topic
51
- end
44
+ # @param topic [String, Symbol] topic
45
+ # @return [String, Symbol] same topic as on input
46
+ # @example
47
+ # outgoing('topic_name') #=> 'topic_name'
48
+ def outgoing(topic)
49
+ topic
52
50
  end
53
51
  end
54
52
  end