semian 0.12.0 → 0.13.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
- data/CHANGELOG.md +235 -0
- data/LICENSE.md +21 -0
- data/README.md +836 -0
- data/ext/semian/extconf.rb +21 -19
- data/lib/semian/adapter.rb +8 -4
- data/lib/semian/circuit_breaker.rb +16 -10
- data/lib/semian/grpc.rb +32 -10
- data/lib/semian/instrumentable.rb +2 -0
- data/lib/semian/lru_hash.rb +15 -14
- data/lib/semian/mysql2.rb +13 -9
- data/lib/semian/net_http.rb +10 -4
- data/lib/semian/platform.rb +3 -1
- data/lib/semian/protected_resource.rb +5 -3
- data/lib/semian/rails.rb +12 -6
- data/lib/semian/redis.rb +15 -13
- data/lib/semian/redis_client.rb +5 -3
- data/lib/semian/resource.rb +5 -3
- data/lib/semian/simple_integer.rb +4 -2
- data/lib/semian/simple_sliding_window.rb +5 -3
- data/lib/semian/simple_state.rb +3 -1
- data/lib/semian/unprotected_resource.rb +2 -0
- data/lib/semian/version.rb +3 -1
- data/lib/semian.rb +61 -45
- metadata +11 -201
    
        data/lib/semian.rb
    CHANGED
    
    | @@ -1,19 +1,21 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 5 | 
            -
             | 
| 6 | 
            -
            require  | 
| 7 | 
            -
             | 
| 8 | 
            -
            require  | 
| 9 | 
            -
            require  | 
| 10 | 
            -
            require  | 
| 11 | 
            -
            require  | 
| 12 | 
            -
            require  | 
| 13 | 
            -
            require  | 
| 14 | 
            -
            require  | 
| 15 | 
            -
            require  | 
| 16 | 
            -
            require  | 
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "forwardable"
         | 
| 4 | 
            +
            require "logger"
         | 
| 5 | 
            +
            require "weakref"
         | 
| 6 | 
            +
            require "thread"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require "semian/version"
         | 
| 9 | 
            +
            require "semian/instrumentable"
         | 
| 10 | 
            +
            require "semian/platform"
         | 
| 11 | 
            +
            require "semian/resource"
         | 
| 12 | 
            +
            require "semian/circuit_breaker"
         | 
| 13 | 
            +
            require "semian/protected_resource"
         | 
| 14 | 
            +
            require "semian/unprotected_resource"
         | 
| 15 | 
            +
            require "semian/simple_sliding_window"
         | 
| 16 | 
            +
            require "semian/simple_integer"
         | 
| 17 | 
            +
            require "semian/simple_state"
         | 
| 18 | 
            +
            require "semian/lru_hash"
         | 
| 17 19 |  | 
| 18 20 | 
             
            #
         | 
| 19 21 | 
             
            # === Overview
         | 
| @@ -56,9 +58,17 @@ require 'semian/lru_hash' | |
| 56 58 | 
             
            #
         | 
| 57 59 | 
             
            # ===== Registering a resource
         | 
| 58 60 | 
             
            #
         | 
| 59 | 
            -
            #    Semian.register( | 
| 61 | 
            +
            #    Semian.register(
         | 
| 62 | 
            +
            #      :mysql_shard0,
         | 
| 63 | 
            +
            #      tickets: 10,
         | 
| 64 | 
            +
            #      timeout: 0.5,
         | 
| 65 | 
            +
            #      error_threshold: 3,
         | 
| 66 | 
            +
            #      error_timeout: 10,
         | 
| 67 | 
            +
            #      success_threshold: 2,
         | 
| 68 | 
            +
            #    )
         | 
| 60 69 | 
             
            #
         | 
| 61 | 
            -
            # This registers a new resource called <code>:mysql_shard0</code> that has 10 tickets and | 
| 70 | 
            +
            # This registers a new resource called <code>:mysql_shard0</code> that has 10 tickets and
         | 
| 71 | 
            +
            # a default timeout of 500 milliseconds.
         | 
| 62 72 | 
             
            #
         | 
| 63 73 | 
             
            # After 3 failures in the span of 10 seconds the circuit will be open.
         | 
| 64 74 | 
             
            # After an additional 10 seconds it will transition to half-open.
         | 
| @@ -70,8 +80,8 @@ require 'semian/lru_hash' | |
| 70 80 | 
             
            #      # Perform a MySQL query here
         | 
| 71 81 | 
             
            #    end
         | 
| 72 82 | 
             
            #
         | 
| 73 | 
            -
            # This acquires a ticket for the <code>:mysql_shard0</code> resource. If we use the example above, | 
| 74 | 
            -
            # be lowered to 9 when block is executed, then raised to 10 when the block completes.
         | 
| 83 | 
            +
            # This acquires a ticket for the <code>:mysql_shard0</code> resource. If we use the example above,
         | 
| 84 | 
            +
            # the ticket count would be lowered to 9 when block is executed, then raised to 10 when the block completes.
         | 
| 75 85 | 
             
            #
         | 
| 76 86 | 
             
            # ===== Overriding the default timeout
         | 
| 77 87 | 
             
            #
         | 
| @@ -79,7 +89,8 @@ require 'semian/lru_hash' | |
| 79 89 | 
             
            #      # Perform a MySQL query here
         | 
| 80 90 | 
             
            #    end
         | 
| 81 91 | 
             
            #
         | 
| 82 | 
            -
            # This is the same as the previous example, but overrides the timeout | 
| 92 | 
            +
            # This is the same as the previous example, but overrides the timeout
         | 
| 93 | 
            +
            # from the default value of 500 milliseconds to 1 second.
         | 
| 83 94 | 
             
            module Semian
         | 
| 84 95 | 
             
              extend self
         | 
| 85 96 | 
             
              extend Instrumentable
         | 
| @@ -91,12 +102,14 @@ module Semian | |
| 91 102 | 
             
              OpenCircuitError = Class.new(BaseError)
         | 
| 92 103 |  | 
| 93 104 | 
             
              attr_accessor :maximum_lru_size, :minimum_lru_time, :default_permissions, :namespace
         | 
| 105 | 
            +
             | 
| 94 106 | 
             
              self.maximum_lru_size = 500
         | 
| 95 107 | 
             
              self.minimum_lru_time = 300
         | 
| 96 108 | 
             
              self.default_permissions = 0660
         | 
| 97 109 |  | 
| 98 110 | 
             
              def issue_disabled_semaphores_warning
         | 
| 99 111 | 
             
                return if defined?(@warning_issued)
         | 
| 112 | 
            +
             | 
| 100 113 | 
             
                @warning_issued = true
         | 
| 101 114 | 
             
                if !sysv_semaphores_supported?
         | 
| 102 115 | 
             
                  logger.info("Semian sysv semaphores are not supported on #{RUBY_PLATFORM} - all operations will no-op")
         | 
| @@ -119,7 +132,7 @@ module Semian | |
| 119 132 |  | 
| 120 133 | 
             
              attr_accessor :logger
         | 
| 121 134 |  | 
| 122 | 
            -
              self.logger = Logger.new( | 
| 135 | 
            +
              self.logger = Logger.new($stderr)
         | 
| 123 136 |  | 
| 124 137 | 
             
              # Registers a resource.
         | 
| 125 138 | 
             
              #
         | 
| @@ -161,7 +174,7 @@ module Semian | |
| 161 174 | 
             
                bulkhead = create_bulkhead(name, **options)
         | 
| 162 175 |  | 
| 163 176 | 
             
                if circuit_breaker.nil? && bulkhead.nil?
         | 
| 164 | 
            -
                  raise ArgumentError,  | 
| 177 | 
            +
                  raise ArgumentError, "Both bulkhead and circuitbreaker cannot be disabled."
         | 
| 165 178 | 
             
                end
         | 
| 166 179 |  | 
| 167 180 | 
             
                resources[name] = ProtectedResource.new(name, bulkhead, circuit_breaker)
         | 
| @@ -170,11 +183,10 @@ module Semian | |
| 170 183 | 
             
              def retrieve_or_register(name, **args)
         | 
| 171 184 | 
             
                # If consumer who retrieved / registered by a Semian::Adapter, keep track
         | 
| 172 185 | 
             
                # of who the consumer was so that we can clear the resource reference if needed.
         | 
| 173 | 
            -
                 | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
                  end
         | 
| 186 | 
            +
                consumer = args.delete(:consumer)
         | 
| 187 | 
            +
                if consumer&.class&.include?(Semian::Adapter)
         | 
| 188 | 
            +
                  consumers[name] ||= []
         | 
| 189 | 
            +
                  consumers[name] << WeakRef.new(consumer)
         | 
| 178 190 | 
             
                end
         | 
| 179 191 | 
             
                self[name] || register(name, **args)
         | 
| 180 192 | 
             
              end
         | 
| @@ -185,9 +197,8 @@ module Semian | |
| 185 197 | 
             
              end
         | 
| 186 198 |  | 
| 187 199 | 
             
              def destroy(name)
         | 
| 188 | 
            -
                 | 
| 189 | 
            -
             | 
| 190 | 
            -
                end
         | 
| 200 | 
            +
                resource = resources.delete(name)
         | 
| 201 | 
            +
                resource&.destroy
         | 
| 191 202 | 
             
              end
         | 
| 192 203 |  | 
| 193 204 | 
             
              def destroy_all_resources
         | 
| @@ -204,17 +215,16 @@ module Semian | |
| 204 215 | 
             
              # Also clears any semian_resources
         | 
| 205 216 | 
             
              # in use by any semian adapters if the weak reference is still alive.
         | 
| 206 217 | 
             
              def unregister(name)
         | 
| 207 | 
            -
                 | 
| 208 | 
            -
             | 
| 218 | 
            +
                resource = resources.delete(name)
         | 
| 219 | 
            +
                if resource
         | 
| 220 | 
            +
                  resource.bulkhead&.unregister_worker
         | 
| 209 221 | 
             
                  consumers_for_resource = consumers.delete(name) || []
         | 
| 210 222 | 
             
                  consumers_for_resource.each do |consumer|
         | 
| 211 | 
            -
                     | 
| 212 | 
            -
                       | 
| 213 | 
            -
                        consumer.clear_semian_resource
         | 
| 214 | 
            -
                      end
         | 
| 215 | 
            -
                    rescue WeakRef::RefError
         | 
| 216 | 
            -
                      next
         | 
| 223 | 
            +
                    if consumer.weakref_alive?
         | 
| 224 | 
            +
                      consumer.clear_semian_resource
         | 
| 217 225 | 
             
                    end
         | 
| 226 | 
            +
                  rescue WeakRef::RefError
         | 
| 227 | 
            +
                    next
         | 
| 218 228 | 
             
                  end
         | 
| 219 229 | 
             
                end
         | 
| 220 230 | 
             
              end
         | 
| @@ -243,6 +253,7 @@ module Semian | |
| 243 253 |  | 
| 244 254 | 
             
              def thread_safe?
         | 
| 245 255 | 
             
                return @thread_safe if defined?(@thread_safe)
         | 
| 256 | 
            +
             | 
| 246 257 | 
             
                @thread_safe = true
         | 
| 247 258 | 
             
              end
         | 
| 248 259 |  | 
| @@ -255,6 +266,7 @@ module Semian | |
| 255 266 | 
             
              def create_circuit_breaker(name, **options)
         | 
| 256 267 | 
             
                circuit_breaker = options.fetch(:circuit_breaker, true)
         | 
| 257 268 | 
             
                return unless circuit_breaker
         | 
| 269 | 
            +
             | 
| 258 270 | 
             
                require_keys!([:success_threshold, :error_threshold, :error_timeout], options)
         | 
| 259 271 |  | 
| 260 272 | 
             
                exceptions = options[:exceptions] || []
         | 
| @@ -277,8 +289,8 @@ module Semian | |
| 277 289 | 
             
                unless options[:thread_safety_disabled].nil?
         | 
| 278 290 | 
             
                  logger.info(
         | 
| 279 291 | 
             
                    "NOTE: thread_safety_disabled will be replaced by a global setting" \
         | 
| 280 | 
            -
             | 
| 281 | 
            -
             | 
| 292 | 
            +
                      "Semian is thread safe by default. It is possible" \
         | 
| 293 | 
            +
                      "to modify the value by using Semian.thread_safe=",
         | 
| 282 294 | 
             
                  )
         | 
| 283 295 | 
             
                end
         | 
| 284 296 |  | 
| @@ -292,7 +304,11 @@ module Semian | |
| 292 304 |  | 
| 293 305 | 
             
                permissions = options[:permissions] || default_permissions
         | 
| 294 306 | 
             
                timeout = options[:timeout] || 0
         | 
| 295 | 
            -
                Resource.new(name, | 
| 307 | 
            +
                ::Semian::Resource.new(name,
         | 
| 308 | 
            +
                  tickets: options[:tickets],
         | 
| 309 | 
            +
                  quota: options[:quota],
         | 
| 310 | 
            +
                  permissions: permissions,
         | 
| 311 | 
            +
                  timeout: timeout)
         | 
| 296 312 | 
             
              end
         | 
| 297 313 |  | 
| 298 314 | 
             
              def require_keys!(required, options)
         | 
| @@ -304,13 +320,13 @@ module Semian | |
| 304 320 | 
             
            end
         | 
| 305 321 |  | 
| 306 322 | 
             
            if Semian.semaphores_enabled?
         | 
| 307 | 
            -
              require  | 
| 323 | 
            +
              require "semian/semian"
         | 
| 308 324 | 
             
            else
         | 
| 309 325 | 
             
              Semian::MAX_TICKETS = 0
         | 
| 310 326 | 
             
            end
         | 
| 311 327 |  | 
| 312 328 | 
             
            if defined? ActiveSupport
         | 
| 313 | 
            -
              ActiveSupport.on_load | 
| 314 | 
            -
                require  | 
| 329 | 
            +
              ActiveSupport.on_load(:active_record) do
         | 
| 330 | 
            +
                require "semian/rails"
         | 
| 315 331 | 
             
              end
         | 
| 316 332 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: semian
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.13.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Scott Francis
         | 
| @@ -10,213 +10,20 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2022- | 
| 14 | 
            -
            dependencies:
         | 
| 15 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 16 | 
            -
              name: rake-compiler
         | 
| 17 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 18 | 
            -
                requirements:
         | 
| 19 | 
            -
                - - ">="
         | 
| 20 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 21 | 
            -
                    version: '0'
         | 
| 22 | 
            -
              type: :development
         | 
| 23 | 
            -
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 25 | 
            -
                requirements:
         | 
| 26 | 
            -
                - - ">="
         | 
| 27 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 28 | 
            -
                    version: '0'
         | 
| 29 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 30 | 
            -
              name: rake
         | 
| 31 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 32 | 
            -
                requirements:
         | 
| 33 | 
            -
                - - ">="
         | 
| 34 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 35 | 
            -
                    version: '0'
         | 
| 36 | 
            -
              type: :development
         | 
| 37 | 
            -
              prerelease: false
         | 
| 38 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 39 | 
            -
                requirements:
         | 
| 40 | 
            -
                - - ">="
         | 
| 41 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 42 | 
            -
                    version: '0'
         | 
| 43 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 44 | 
            -
              name: timecop
         | 
| 45 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 46 | 
            -
                requirements:
         | 
| 47 | 
            -
                - - ">="
         | 
| 48 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 49 | 
            -
                    version: '0'
         | 
| 50 | 
            -
              type: :development
         | 
| 51 | 
            -
              prerelease: false
         | 
| 52 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 53 | 
            -
                requirements:
         | 
| 54 | 
            -
                - - ">="
         | 
| 55 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 56 | 
            -
                    version: '0'
         | 
| 57 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 58 | 
            -
              name: minitest
         | 
| 59 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 60 | 
            -
                requirements:
         | 
| 61 | 
            -
                - - ">="
         | 
| 62 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 63 | 
            -
                    version: '0'
         | 
| 64 | 
            -
              type: :development
         | 
| 65 | 
            -
              prerelease: false
         | 
| 66 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 67 | 
            -
                requirements:
         | 
| 68 | 
            -
                - - ">="
         | 
| 69 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 70 | 
            -
                    version: '0'
         | 
| 71 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 72 | 
            -
              name: pry-byebug
         | 
| 73 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 74 | 
            -
                requirements:
         | 
| 75 | 
            -
                - - ">="
         | 
| 76 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 77 | 
            -
                    version: '0'
         | 
| 78 | 
            -
              type: :development
         | 
| 79 | 
            -
              prerelease: false
         | 
| 80 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 81 | 
            -
                requirements:
         | 
| 82 | 
            -
                - - ">="
         | 
| 83 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 84 | 
            -
                    version: '0'
         | 
| 85 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 86 | 
            -
              name: mysql2
         | 
| 87 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 88 | 
            -
                requirements:
         | 
| 89 | 
            -
                - - ">="
         | 
| 90 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 91 | 
            -
                    version: '0'
         | 
| 92 | 
            -
              type: :development
         | 
| 93 | 
            -
              prerelease: false
         | 
| 94 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 95 | 
            -
                requirements:
         | 
| 96 | 
            -
                - - ">="
         | 
| 97 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 98 | 
            -
                    version: '0'
         | 
| 99 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 100 | 
            -
              name: redis
         | 
| 101 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 102 | 
            -
                requirements:
         | 
| 103 | 
            -
                - - ">="
         | 
| 104 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 105 | 
            -
                    version: '0'
         | 
| 106 | 
            -
              type: :development
         | 
| 107 | 
            -
              prerelease: false
         | 
| 108 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 109 | 
            -
                requirements:
         | 
| 110 | 
            -
                - - ">="
         | 
| 111 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 112 | 
            -
                    version: '0'
         | 
| 113 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 114 | 
            -
              name: redis-client
         | 
| 115 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 116 | 
            -
                requirements:
         | 
| 117 | 
            -
                - - ">="
         | 
| 118 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 119 | 
            -
                    version: 0.2.0
         | 
| 120 | 
            -
              type: :development
         | 
| 121 | 
            -
              prerelease: false
         | 
| 122 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 123 | 
            -
                requirements:
         | 
| 124 | 
            -
                - - ">="
         | 
| 125 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 126 | 
            -
                    version: 0.2.0
         | 
| 127 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 128 | 
            -
              name: webrick
         | 
| 129 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 130 | 
            -
                requirements:
         | 
| 131 | 
            -
                - - ">="
         | 
| 132 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 133 | 
            -
                    version: '0'
         | 
| 134 | 
            -
              type: :development
         | 
| 135 | 
            -
              prerelease: false
         | 
| 136 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 137 | 
            -
                requirements:
         | 
| 138 | 
            -
                - - ">="
         | 
| 139 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 140 | 
            -
                    version: '0'
         | 
| 141 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 142 | 
            -
              name: toxiproxy
         | 
| 143 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 144 | 
            -
                requirements:
         | 
| 145 | 
            -
                - - "~>"
         | 
| 146 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 147 | 
            -
                    version: 1.0.0
         | 
| 148 | 
            -
              type: :development
         | 
| 149 | 
            -
              prerelease: false
         | 
| 150 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 151 | 
            -
                requirements:
         | 
| 152 | 
            -
                - - "~>"
         | 
| 153 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 154 | 
            -
                    version: 1.0.0
         | 
| 155 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 156 | 
            -
              name: grpc
         | 
| 157 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 158 | 
            -
                requirements:
         | 
| 159 | 
            -
                - - ">="
         | 
| 160 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 161 | 
            -
                    version: '0'
         | 
| 162 | 
            -
              type: :development
         | 
| 163 | 
            -
              prerelease: false
         | 
| 164 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 165 | 
            -
                requirements:
         | 
| 166 | 
            -
                - - ">="
         | 
| 167 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 168 | 
            -
                    version: '0'
         | 
| 169 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 170 | 
            -
              name: mocha
         | 
| 171 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 172 | 
            -
                requirements:
         | 
| 173 | 
            -
                - - ">="
         | 
| 174 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 175 | 
            -
                    version: '0'
         | 
| 176 | 
            -
              type: :development
         | 
| 177 | 
            -
              prerelease: false
         | 
| 178 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 179 | 
            -
                requirements:
         | 
| 180 | 
            -
                - - ">="
         | 
| 181 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 182 | 
            -
                    version: '0'
         | 
| 183 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 184 | 
            -
              name: memory_profiler
         | 
| 185 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 186 | 
            -
                requirements:
         | 
| 187 | 
            -
                - - ">="
         | 
| 188 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 189 | 
            -
                    version: '0'
         | 
| 190 | 
            -
              type: :development
         | 
| 191 | 
            -
              prerelease: false
         | 
| 192 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 193 | 
            -
                requirements:
         | 
| 194 | 
            -
                - - ">="
         | 
| 195 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 196 | 
            -
                    version: '0'
         | 
| 197 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 198 | 
            -
              name: benchmark-memory
         | 
| 199 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 200 | 
            -
                requirements:
         | 
| 201 | 
            -
                - - ">="
         | 
| 202 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 203 | 
            -
                    version: '0'
         | 
| 204 | 
            -
              type: :development
         | 
| 205 | 
            -
              prerelease: false
         | 
| 206 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 207 | 
            -
                requirements:
         | 
| 208 | 
            -
                - - ">="
         | 
| 209 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 210 | 
            -
                    version: '0'
         | 
| 13 | 
            +
            date: 2022-06-27 00:00:00.000000000 Z
         | 
| 14 | 
            +
            dependencies: []
         | 
| 211 15 | 
             
            description: |2
         | 
| 212 16 | 
             
                  A Ruby C extention that is used to control access to shared resources
         | 
| 213 17 | 
             
                  across process boundaries with SysV semaphores.
         | 
| 214 | 
            -
            email:  | 
| 18 | 
            +
            email: opensource@shopify.com
         | 
| 215 19 | 
             
            executables: []
         | 
| 216 20 | 
             
            extensions:
         | 
| 217 21 | 
             
            - ext/semian/extconf.rb
         | 
| 218 22 | 
             
            extra_rdoc_files: []
         | 
| 219 23 | 
             
            files:
         | 
| 24 | 
            +
            - CHANGELOG.md
         | 
| 25 | 
            +
            - LICENSE.md
         | 
| 26 | 
            +
            - README.md
         | 
| 220 27 | 
             
            - ext/semian/extconf.rb
         | 
| 221 28 | 
             
            - ext/semian/resource.c
         | 
| 222 29 | 
             
            - ext/semian/resource.h
         | 
| @@ -251,6 +58,9 @@ licenses: | |
| 251 58 | 
             
            - MIT
         | 
| 252 59 | 
             
            metadata:
         | 
| 253 60 | 
             
              allowed_push_host: https://rubygems.org
         | 
| 61 | 
            +
              bug_tracker_uri: https://github.com/Shopify/semian/issues
         | 
| 62 | 
            +
              changelog_uri: https://github.com/Shopify/semian/blob/master/CHANGELOG.md
         | 
| 63 | 
            +
              source_code_uri: https://github.com/Shopify/semian
         | 
| 254 64 | 
             
            post_install_message: 
         | 
| 255 65 | 
             
            rdoc_options: []
         | 
| 256 66 | 
             
            require_paths:
         | 
| @@ -266,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 266 76 | 
             
                - !ruby/object:Gem::Version
         | 
| 267 77 | 
             
                  version: '0'
         | 
| 268 78 | 
             
            requirements: []
         | 
| 269 | 
            -
            rubygems_version: 3. | 
| 79 | 
            +
            rubygems_version: 3.3.3
         | 
| 270 80 | 
             
            signing_key: 
         | 
| 271 81 | 
             
            specification_version: 4
         | 
| 272 82 | 
             
            summary: Bulkheading for Ruby with SysV semaphores
         |