karafka-core 2.4.0 → 2.4.1.rc1
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/workflows/ci.yml +1 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +13 -12
- data/lib/karafka/core/contractable/contract.rb +20 -18
- data/lib/karafka/core/helpers/time.rb +11 -4
- data/lib/karafka/core/monitoring/notifications.rb +34 -22
- data/lib/karafka/core/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +3 -3
- metadata.gz.sig +0 -0
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f3f54f6bc0338e84c7875cb5b62ca56a32f9c25d20e264fb82ee7e0d8e60b0a8
         | 
| 4 | 
            +
              data.tar.gz: ac1ed9d339f2389d2f177c7522ce866fb6b6e291ed38d58e859c6cbe7994fcf8
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 6d32caa0580cea62b988bd7966c1e6e553f192a8ab765d1cb060480e9b4d1e3494959f05cd11f4a0033110bd2b08bb6acc884c8a2baf877639ec201c2a889d80
         | 
| 7 | 
            +
              data.tar.gz: 78422668f5de7a67c7c29504cf727ed57e9834b0aa6910959a21d733cf248e97043ba0ae854a5cfb75ff099af81da41b500f36fa2e99ac426c28fa29868979a0
         | 
    
        checksums.yaml.gz.sig
    CHANGED
    
    | Binary file | 
    
        data/.github/workflows/ci.yml
    CHANGED
    
    
    
        data/.ruby-version
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            3.3. | 
| 1 | 
            +
            3.3.3
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,13 @@ | |
| 1 1 | 
             
            # Karafka core changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 2.4.1 (Unreleased)
         | 
| 4 | 
            +
            - [Enhancement] Provide fast-track for events without subscriptions to save on allocations.
         | 
| 5 | 
            +
            - [Enhancement] Save memory allocation on each contract rule validation execution.
         | 
| 6 | 
            +
            - [Enhancement] Save one allocation per `float_now` + 2-3x performance by using the Posix clock instead of `Time.now.utc.to_f`.
         | 
| 7 | 
            +
            - [Enhancement] Use direct `float_millisecond` precision in `monotonic_now` not to multiply by 1000 (allocations and CPU savings).
         | 
| 8 | 
            +
            - [Enhancement] Save one array allocation on one instrumentation.
         | 
| 9 | 
            +
            - [Enhancement] Allow clearing one event type (dorner).
         | 
| 10 | 
            +
             | 
| 3 11 | 
             
            ## 2.4.0 (2024-04-26)
         | 
| 4 12 | 
             
            - **[Breaking]** Drop Ruby `2.7` support.
         | 
| 5 13 | 
             
            - [Enhancement] Provide necessary alterations for custom oauth token callbacks to operate.
         | 
    
        data/Gemfile.lock
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            PATH
         | 
| 2 2 | 
             
              remote: .
         | 
| 3 3 | 
             
              specs:
         | 
| 4 | 
            -
                karafka-core (2.4. | 
| 4 | 
            +
                karafka-core (2.4.1.rc1)
         | 
| 5 5 | 
             
                  karafka-rdkafka (>= 0.15.0, < 0.16.0)
         | 
| 6 6 |  | 
| 7 7 | 
             
            GEM
         | 
| 8 8 | 
             
              remote: https://rubygems.org/
         | 
| 9 9 | 
             
              specs:
         | 
| 10 | 
            -
                activesupport (7.1.3. | 
| 10 | 
            +
                activesupport (7.1.3.4)
         | 
| 11 11 | 
             
                  base64
         | 
| 12 12 | 
             
                  bigdecimal
         | 
| 13 13 | 
             
                  concurrent-ruby (~> 1.0, >= 1.0.2)
         | 
| @@ -18,24 +18,25 @@ GEM | |
| 18 18 | 
             
                  mutex_m
         | 
| 19 19 | 
             
                  tzinfo (~> 2.0)
         | 
| 20 20 | 
             
                base64 (0.2.0)
         | 
| 21 | 
            -
                bigdecimal (3.1. | 
| 21 | 
            +
                bigdecimal (3.1.8)
         | 
| 22 22 | 
             
                byebug (11.1.3)
         | 
| 23 | 
            -
                concurrent-ruby (1. | 
| 23 | 
            +
                concurrent-ruby (1.3.3)
         | 
| 24 24 | 
             
                connection_pool (2.4.1)
         | 
| 25 25 | 
             
                diff-lcs (1.5.1)
         | 
| 26 26 | 
             
                docile (1.4.0)
         | 
| 27 27 | 
             
                drb (2.2.1)
         | 
| 28 28 | 
             
                factory_bot (6.4.6)
         | 
| 29 29 | 
             
                  activesupport (>= 5.0.0)
         | 
| 30 | 
            -
                ffi (1. | 
| 31 | 
            -
                 | 
| 30 | 
            +
                ffi (1.17.0)
         | 
| 31 | 
            +
                ffi (1.17.0-x86_64-linux-gnu)
         | 
| 32 | 
            +
                i18n (1.14.5)
         | 
| 32 33 | 
             
                  concurrent-ruby (~> 1.0)
         | 
| 33 | 
            -
                karafka-rdkafka (0.15. | 
| 34 | 
            +
                karafka-rdkafka (0.15.1)
         | 
| 34 35 | 
             
                  ffi (~> 1.15)
         | 
| 35 36 | 
             
                  mini_portile2 (~> 2.6)
         | 
| 36 37 | 
             
                  rake (> 12)
         | 
| 37 | 
            -
                mini_portile2 (2.8. | 
| 38 | 
            -
                minitest (5. | 
| 38 | 
            +
                mini_portile2 (2.8.7)
         | 
| 39 | 
            +
                minitest (5.23.1)
         | 
| 39 40 | 
             
                mutex_m (0.2.0)
         | 
| 40 41 | 
             
                rake (13.2.1)
         | 
| 41 42 | 
             
                rspec (3.13.0)
         | 
| @@ -44,10 +45,10 @@ GEM | |
| 44 45 | 
             
                  rspec-mocks (~> 3.13.0)
         | 
| 45 46 | 
             
                rspec-core (3.13.0)
         | 
| 46 47 | 
             
                  rspec-support (~> 3.13.0)
         | 
| 47 | 
            -
                rspec-expectations (3.13. | 
| 48 | 
            +
                rspec-expectations (3.13.1)
         | 
| 48 49 | 
             
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 49 50 | 
             
                  rspec-support (~> 3.13.0)
         | 
| 50 | 
            -
                rspec-mocks (3.13. | 
| 51 | 
            +
                rspec-mocks (3.13.1)
         | 
| 51 52 | 
             
                  diff-lcs (>= 1.2.0, < 2.0)
         | 
| 52 53 | 
             
                  rspec-support (~> 3.13.0)
         | 
| 53 54 | 
             
                rspec-support (3.13.1)
         | 
| @@ -72,4 +73,4 @@ DEPENDENCIES | |
| 72 73 | 
             
              simplecov
         | 
| 73 74 |  | 
| 74 75 | 
             
            BUNDLED WITH
         | 
| 75 | 
            -
               2.5. | 
| 76 | 
            +
               2.5.13
         | 
| @@ -9,6 +9,13 @@ module Karafka | |
| 9 9 | 
             
                  class Contract
         | 
| 10 10 | 
             
                    extend Core::Configurable
         | 
| 11 11 |  | 
| 12 | 
            +
                    # Constant representing a miss during dig
         | 
| 13 | 
            +
                    # We use it as a result value not to return an array with found object and a state to
         | 
| 14 | 
            +
                    # prevent additional array allocation
         | 
| 15 | 
            +
                    DIG_MISS = BasicObject.new
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                    private_constant :DIG_MISS
         | 
| 18 | 
            +
             | 
| 12 19 | 
             
                    # Yaml based error messages data
         | 
| 13 20 | 
             
                    setting(:error_messages)
         | 
| 14 21 |  | 
| @@ -75,7 +82,7 @@ module Karafka | |
| 75 82 | 
             
                    def call(data)
         | 
| 76 83 | 
             
                      errors = []
         | 
| 77 84 |  | 
| 78 | 
            -
                      self.class.rules. | 
| 85 | 
            +
                      self.class.rules.each do |rule|
         | 
| 79 86 | 
             
                        case rule.type
         | 
| 80 87 | 
             
                        when :required
         | 
| 81 88 | 
             
                          validate_required(data, rule, errors)
         | 
| @@ -113,14 +120,14 @@ module Karafka | |
| 113 120 | 
             
                    def validate_required(data, rule, errors)
         | 
| 114 121 | 
             
                      for_checking = dig(data, rule.path)
         | 
| 115 122 |  | 
| 116 | 
            -
                      if for_checking | 
| 117 | 
            -
                         | 
| 123 | 
            +
                      if for_checking == DIG_MISS
         | 
| 124 | 
            +
                        errors << [rule.path, :missing]
         | 
| 125 | 
            +
                      else
         | 
| 126 | 
            +
                        result = rule.validator.call(for_checking, data, errors, self)
         | 
| 118 127 |  | 
| 119 128 | 
             
                        return if result == true
         | 
| 120 129 |  | 
| 121 130 | 
             
                        errors << [rule.path, result || :format]
         | 
| 122 | 
            -
                      else
         | 
| 123 | 
            -
                        errors << [rule.path, :missing]
         | 
| 124 131 | 
             
                      end
         | 
| 125 132 | 
             
                    end
         | 
| 126 133 |  | 
| @@ -133,9 +140,9 @@ module Karafka | |
| 133 140 | 
             
                    def validate_optional(data, rule, errors)
         | 
| 134 141 | 
             
                      for_checking = dig(data, rule.path)
         | 
| 135 142 |  | 
| 136 | 
            -
                      return  | 
| 143 | 
            +
                      return if for_checking == DIG_MISS
         | 
| 137 144 |  | 
| 138 | 
            -
                      result = rule.validator.call(for_checking | 
| 145 | 
            +
                      result = rule.validator.call(for_checking, data, errors, self)
         | 
| 139 146 |  | 
| 140 147 | 
             
                      return if result == true
         | 
| 141 148 |  | 
| @@ -156,28 +163,23 @@ module Karafka | |
| 156 163 | 
             
                      errors.push(*result)
         | 
| 157 164 | 
             
                    end
         | 
| 158 165 |  | 
| 159 | 
            -
                    # Tries to dig for a given key in a hash and returns it with indication whether or not it | 
| 160 | 
            -
                    # possible to find it (dig returns nil and we don't know if it wasn't the digged key | 
| 166 | 
            +
                    # Tries to dig for a given key in a hash and returns it with indication whether or not it
         | 
| 167 | 
            +
                    # was possible to find it (dig returns nil and we don't know if it wasn't the digged key
         | 
| 168 | 
            +
                    # value)
         | 
| 161 169 | 
             
                    #
         | 
| 162 170 | 
             
                    # @param data [Hash]
         | 
| 163 171 | 
             
                    # @param keys [Array<Symbol>]
         | 
| 164 | 
            -
                    # @return [ | 
| 165 | 
            -
                    #   the digged value or nil if not found
         | 
| 172 | 
            +
                    # @return [DIG_MISS, Object] found element or DIGG_MISS indicating that not found
         | 
| 166 173 | 
             
                    def dig(data, keys)
         | 
| 167 174 | 
             
                      current = data
         | 
| 168 | 
            -
                      result = :match
         | 
| 169 175 |  | 
| 170 176 | 
             
                      keys.each do |nesting|
         | 
| 171 | 
            -
                        unless current.key?(nesting)
         | 
| 172 | 
            -
                          result = :miss
         | 
| 173 | 
            -
             | 
| 174 | 
            -
                          break
         | 
| 175 | 
            -
                        end
         | 
| 177 | 
            +
                        return DIG_MISS unless current.key?(nesting)
         | 
| 176 178 |  | 
| 177 179 | 
             
                        current = current[nesting]
         | 
| 178 180 | 
             
                      end
         | 
| 179 181 |  | 
| 180 | 
            -
                       | 
| 182 | 
            +
                      current
         | 
| 181 183 | 
             
                    end
         | 
| 182 184 | 
             
                  end
         | 
| 183 185 | 
             
                end
         | 
| @@ -6,14 +6,21 @@ module Karafka | |
| 6 6 | 
             
                module Helpers
         | 
| 7 7 | 
             
                  # Time related methods used across Karafka
         | 
| 8 8 | 
             
                  module Time
         | 
| 9 | 
            -
                     | 
| 10 | 
            -
             | 
| 11 | 
            -
                       | 
| 9 | 
            +
                    if RUBY_VERSION >= '3.2'
         | 
| 10 | 
            +
                      # @return [Float] current monotonic time in milliseconds
         | 
| 11 | 
            +
                      def monotonic_now
         | 
| 12 | 
            +
                        ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :float_millisecond)
         | 
| 13 | 
            +
                      end
         | 
| 14 | 
            +
                    else
         | 
| 15 | 
            +
                      # @return [Float] current monotonic time in milliseconds
         | 
| 16 | 
            +
                      def monotonic_now
         | 
| 17 | 
            +
                        ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) * 1_000
         | 
| 18 | 
            +
                      end
         | 
| 12 19 | 
             
                    end
         | 
| 13 20 |  | 
| 14 21 | 
             
                    # @return [Float] current time in float
         | 
| 15 22 | 
             
                    def float_now
         | 
| 16 | 
            -
                      :: | 
| 23 | 
            +
                      ::Process.clock_gettime(::Process::CLOCK_REALTIME)
         | 
| 17 24 | 
             
                    end
         | 
| 18 25 | 
             
                  end
         | 
| 19 26 | 
             
                end
         | 
| @@ -22,7 +22,7 @@ module Karafka | |
| 22 22 | 
             
                    private_constant :EMPTY_HASH
         | 
| 23 23 |  | 
| 24 24 | 
             
                    def initialize
         | 
| 25 | 
            -
                      @listeners =  | 
| 25 | 
            +
                      @listeners = {}
         | 
| 26 26 | 
             
                      @mutex = Mutex.new
         | 
| 27 27 | 
             
                      # This allows us to optimize the method calling lookups
         | 
| 28 28 | 
             
                      @events_methods_map = {}
         | 
| @@ -33,15 +33,20 @@ module Karafka | |
| 33 33 | 
             
                    # @param event_id [String] event id
         | 
| 34 34 | 
             
                    def register_event(event_id)
         | 
| 35 35 | 
             
                      @mutex.synchronize do
         | 
| 36 | 
            -
                        @listeners[event_id]
         | 
| 36 | 
            +
                        @listeners[event_id] = []
         | 
| 37 37 | 
             
                        @events_methods_map[event_id] = :"on_#{event_id.to_s.tr('.', '_')}"
         | 
| 38 38 | 
             
                      end
         | 
| 39 39 | 
             
                    end
         | 
| 40 40 |  | 
| 41 | 
            -
                    # Clears all the subscribed listeners
         | 
| 42 | 
            -
                     | 
| 41 | 
            +
                    # Clears all the subscribed listeners. If given an event, only clear listeners for the given
         | 
| 42 | 
            +
                    # event type.
         | 
| 43 | 
            +
                    # @param event_id [String] the key of the event to clear listeners for.
         | 
| 44 | 
            +
                    def clear(event_id = nil)
         | 
| 43 45 | 
             
                      @mutex.synchronize do
         | 
| 44 | 
            -
                        @listeners.each_value(&:clear)
         | 
| 46 | 
            +
                        return @listeners.each_value(&:clear) unless event_id
         | 
| 47 | 
            +
                        return @listeners[event_id].clear if @listeners.key?(event_id)
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                        raise(EventNotRegistered, "#{event_id} not registered!")
         | 
| 45 50 | 
             
                      end
         | 
| 46 51 | 
             
                    end
         | 
| 47 52 |  | 
| @@ -84,25 +89,42 @@ module Karafka | |
| 84 89 | 
             
                    #
         | 
| 85 90 | 
             
                    # @param event_id [String] id of the event
         | 
| 86 91 | 
             
                    # @param payload [Hash] payload for the instrumentation
         | 
| 87 | 
            -
                    # @ | 
| 92 | 
            +
                    # @yield [Proc] instrumented code
         | 
| 88 93 | 
             
                    # @return [Object] whatever the provided block (if any) returns
         | 
| 89 94 | 
             
                    #
         | 
| 90 95 | 
             
                    # @example Instrument some code
         | 
| 91 96 | 
             
                    #   instrument('sleeping') do
         | 
| 92 97 | 
             
                    #     sleep(1)
         | 
| 93 98 | 
             
                    #   end
         | 
| 94 | 
            -
                    def instrument(event_id, payload = EMPTY_HASH | 
| 95 | 
            -
                       | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
                       | 
| 99 | 
            +
                    def instrument(event_id, payload = EMPTY_HASH)
         | 
| 100 | 
            +
                      assigned_listeners = @listeners[event_id]
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                      # Allow for instrumentation of only events we registered. If listeners array does not
         | 
| 103 | 
            +
                      # exist, it means the event was not registered.
         | 
| 104 | 
            +
                      raise EventNotRegistered, event_id unless assigned_listeners
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                      if block_given?
         | 
| 107 | 
            +
                        # No point in instrumentation when no one is listening
         | 
| 108 | 
            +
                        # Since the outcome will be ignored, we may as well save on allocations
         | 
| 109 | 
            +
                        # There are many events that happen often like (`message.acknowledged`) that most
         | 
| 110 | 
            +
                        # users do not subscribe to. Such check prevents us from publishing events that would
         | 
| 111 | 
            +
                        # not be used at all saving on time measurements and objects allocations
         | 
| 112 | 
            +
                        return yield if assigned_listeners.empty?
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                        start = monotonic_now
         | 
| 115 | 
            +
                        result = yield
         | 
| 116 | 
            +
                        time = monotonic_now - start
         | 
| 117 | 
            +
                      elsif assigned_listeners.empty?
         | 
| 118 | 
            +
                        # Skip measuring or doing anything if no one listening
         | 
| 119 | 
            +
                        return
         | 
| 120 | 
            +
                      end
         | 
| 99 121 |  | 
| 100 122 | 
             
                      event = Event.new(
         | 
| 101 123 | 
             
                        event_id,
         | 
| 102 124 | 
             
                        time ? payload.merge(time: time) : payload
         | 
| 103 125 | 
             
                      )
         | 
| 104 126 |  | 
| 105 | 
            -
                       | 
| 127 | 
            +
                      assigned_listeners.each do |listener|
         | 
| 106 128 | 
             
                        if listener.is_a?(Proc)
         | 
| 107 129 | 
             
                          listener.call(event)
         | 
| 108 130 | 
             
                        else
         | 
| @@ -112,16 +134,6 @@ module Karafka | |
| 112 134 |  | 
| 113 135 | 
             
                      result
         | 
| 114 136 | 
             
                    end
         | 
| 115 | 
            -
             | 
| 116 | 
            -
                    private
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                    # Measures time taken to execute a given block and returns it together with the result of
         | 
| 119 | 
            -
                    # the block execution
         | 
| 120 | 
            -
                    def measure_time_taken
         | 
| 121 | 
            -
                      start = monotonic_now
         | 
| 122 | 
            -
                      result = yield
         | 
| 123 | 
            -
                      [result, monotonic_now - start]
         | 
| 124 | 
            -
                    end
         | 
| 125 137 | 
             
                  end
         | 
| 126 138 | 
             
                end
         | 
| 127 139 | 
             
              end
         | 
    
        data/lib/karafka/core/version.rb
    CHANGED
    
    
    
        data.tar.gz.sig
    CHANGED
    
    | Binary file | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: karafka-core
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.4. | 
| 4 | 
            +
              version: 2.4.1.rc1
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Maciej Mensfeld
         | 
| @@ -35,7 +35,7 @@ cert_chain: | |
| 35 35 | 
             
              AnG1dJU+yL2BK7vaVytLTstJME5mepSZ46qqIJXMuWob/YPDmVaBF39TDSG9e34s
         | 
| 36 36 | 
             
              msG3BiCqgOgHAnL23+CN3Rt8MsuRfEtoTKpJVcCfoEoNHOkc
         | 
| 37 37 | 
             
              -----END CERTIFICATE-----
         | 
| 38 | 
            -
            date: 2024- | 
| 38 | 
            +
            date: 2024-06-17 00:00:00.000000000 Z
         | 
| 39 39 | 
             
            dependencies:
         | 
| 40 40 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 41 41 | 
             
              name: karafka-rdkafka
         | 
| @@ -134,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 134 134 | 
             
                - !ruby/object:Gem::Version
         | 
| 135 135 | 
             
                  version: '0'
         | 
| 136 136 | 
             
            requirements: []
         | 
| 137 | 
            -
            rubygems_version: 3.5. | 
| 137 | 
            +
            rubygems_version: 3.5.11
         | 
| 138 138 | 
             
            signing_key: 
         | 
| 139 139 | 
             
            specification_version: 4
         | 
| 140 140 | 
             
            summary: Karafka ecosystem core modules
         | 
    
        metadata.gz.sig
    CHANGED
    
    | Binary file |