nn-core 0.1.5 → 0.1.6
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.
- data/History.txt +13 -0
- data/examples/roundtrip_latency.rb +167 -0
- data/lib/nn-core/libnanomsg.rb +16 -0
- data/lib/nn-core/version.rb +1 -1
- data/spec/nn_connect_spec.rb +17 -24
- data/spec/nn_recv_spec.rb +4 -1
- data/spec/nn_socket_spec.rb +4 -5
- data/spec/nn_version_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +16 -14
    
        data/History.txt
    CHANGED
    
    | @@ -1,3 +1,16 @@ | |
| 1 | 
            +
            20130220 / 0.1.6
         | 
| 2 | 
            +
            	* Several fixes for tcp string handling have made it to nanomsg trunk,
         | 
| 3 | 
            +
            		so I can now re-enable those specs.
         | 
| 4 | 
            +
            		
         | 
| 5 | 
            +
            	*	For MRI Ruby, add @blocking=true before all function attachments to instruct
         | 
| 6 | 
            +
            		the FFI gem to release the GIL.
         | 
| 7 | 
            +
            		
         | 
| 8 | 
            +
            	*	Fixed a nn_recv spec to only read a specific number of bytes from a received
         | 
| 9 | 
            +
            		string. Must note that the library does not null terminate strings on its
         | 
| 10 | 
            +
            		own so we need to be very careful how many bytes are read from received
         | 
| 11 | 
            +
            		strings.
         | 
| 12 | 
            +
            		
         | 
| 13 | 
            +
             | 
| 1 14 | 
             
            20130215 / 0.1.5
         | 
| 2 15 | 
             
            	*	libnanomsg has removed the nn_init and nn_term functions. Updated
         | 
| 3 16 | 
             
            		specs to remove those features.
         | 
| @@ -0,0 +1,167 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              require 'nn-core'
         | 
| 3 | 
            +
            rescue LoadError
         | 
| 4 | 
            +
              $: << File.join(File.dirname(__FILE__), '..', 'lib')
         | 
| 5 | 
            +
              retry
         | 
| 6 | 
            +
            end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
             | 
| 9 | 
            +
            # Within a single process, we start up two threads. One thread has a REQ (request)
         | 
| 10 | 
            +
            # socket and the second thread has a REP (reply) socket. We measure the
         | 
| 11 | 
            +
            # *round-trip* latency between these sockets. Only *one* message is in flight at
         | 
| 12 | 
            +
            # any given moment.
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            #  % ruby roundtrip_latency.rb tcp://127.0.0.1:5555 1024 1_000_000
         | 
| 15 | 
            +
            #
         | 
| 16 | 
            +
            #  % ruby roundtrip_latency.rb inproc://lm_sock 1024 1_000_000
         | 
| 17 | 
            +
            #
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            if ARGV.length < 3
         | 
| 20 | 
            +
              puts "usage: ruby roundtrip_latency.rb <connect-to> <message-size> <roundtrip-count>"
         | 
| 21 | 
            +
              exit
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            link = ARGV[0]
         | 
| 25 | 
            +
            message_size = ARGV[1].to_i
         | 
| 26 | 
            +
            roundtrip_count = ARGV[2].to_i
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            def set_signal_handler(receiver, transmitter)
         | 
| 29 | 
            +
              trap(:INT) do
         | 
| 30 | 
            +
                puts "got ctrl-c"
         | 
| 31 | 
            +
                receiver.terminate
         | 
| 32 | 
            +
                transmitter.terminate
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            class Node
         | 
| 37 | 
            +
              def initialize(endpoint, size, count)
         | 
| 38 | 
            +
                @endpoint = endpoint
         | 
| 39 | 
            +
                @size = size
         | 
| 40 | 
            +
                @count = count
         | 
| 41 | 
            +
                @msg = 'a' * @size
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                @rcv_buffer = FFI::MemoryPointer.new(@size)
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                allocate_socket
         | 
| 46 | 
            +
                setup_socket
         | 
| 47 | 
            +
                set_endpoint
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def setup_socket
         | 
| 51 | 
            +
                option = FFI::MemoryPointer.new(:int32)
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                # LINGER
         | 
| 54 | 
            +
                option.write_int(100)
         | 
| 55 | 
            +
                rc = NNCore::LibNanomsg.nn_setsockopt(@socket, NNCore::NN_SOL_SOCKET, NNCore::NN_LINGER, option, 4)
         | 
| 56 | 
            +
                assert(rc)
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                # SNDBUF
         | 
| 59 | 
            +
                option.write_int(131072)
         | 
| 60 | 
            +
                rc = NNCore::LibNanomsg.nn_setsockopt(@socket, NNCore::NN_SOL_SOCKET, NNCore::NN_SNDBUF, option, 4)
         | 
| 61 | 
            +
                assert(rc)
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                # RCVBUF
         | 
| 64 | 
            +
                option.write_int(131072)
         | 
| 65 | 
            +
                rc = NNCore::LibNanomsg.nn_setsockopt(@socket, NNCore::NN_SOL_SOCKET, NNCore::NN_RCVBUF, option, 4)
         | 
| 66 | 
            +
                assert(rc)
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              def send_msg
         | 
| 70 | 
            +
                nbytes = NNCore::LibNanomsg.nn_send(@socket, @msg, @size, 0)
         | 
| 71 | 
            +
                assert(nbytes)
         | 
| 72 | 
            +
                nbytes
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def recv_msg
         | 
| 76 | 
            +
                nbytes = NNCore::LibNanomsg.nn_recv(@socket, @rcv_buffer, @size, 0)
         | 
| 77 | 
            +
                assert(nbytes)
         | 
| 78 | 
            +
                nbytes
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              def terminate
         | 
| 82 | 
            +
                assert(NNCore::LibNanomsg.nn_close(@socket))
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              def assert(rc)
         | 
| 86 | 
            +
                raise "Last API call failed at #{caller(1)}" unless rc >= 0
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
            end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
            class Receiver < Node
         | 
| 91 | 
            +
              def allocate_socket
         | 
| 92 | 
            +
                @socket = NNCore::LibNanomsg.nn_socket(NNCore::AF_SP, NNCore::NN_REP)
         | 
| 93 | 
            +
                assert(@socket)
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              def set_endpoint
         | 
| 97 | 
            +
                assert(NNCore::LibNanomsg.nn_bind(@socket, @endpoint))
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              def run
         | 
| 101 | 
            +
                @count.times do
         | 
| 102 | 
            +
                  nbytes = recv_msg
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  raise "Message size doesn't match, expected [#{@size}] but received [#{string.size}]" if @size != nbytes
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  send_msg
         | 
| 107 | 
            +
                end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                terminate
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
            end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
            class Transmitter < Node
         | 
| 114 | 
            +
              def allocate_socket
         | 
| 115 | 
            +
                @socket = NNCore::LibNanomsg.nn_socket(NNCore::AF_SP, NNCore::NN_REQ)
         | 
| 116 | 
            +
                assert(@socket)
         | 
| 117 | 
            +
              end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
              def set_endpoint
         | 
| 120 | 
            +
                assert(NNCore::LibNanomsg.nn_connect(@socket, @endpoint))
         | 
| 121 | 
            +
              end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
              def run
         | 
| 124 | 
            +
                elapsed = elapsed_microseconds do
         | 
| 125 | 
            +
                  @count.times do
         | 
| 126 | 
            +
                    send_msg
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                    nbytes = recv_msg
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    raise "Message size doesn't match, expected [#{@size}] but received [#{nbytes}]" if @size != nbytes
         | 
| 131 | 
            +
                  end
         | 
| 132 | 
            +
                end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                latency = elapsed / @count / 2
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                puts "message size: %i [B]" % @size
         | 
| 137 | 
            +
                puts "roundtrip count: %i" % @count
         | 
| 138 | 
            +
                puts "throughput (msgs/s): %i" % (@count / (elapsed / 1_000_000))
         | 
| 139 | 
            +
                puts "mean latency: %.3f [us]" % latency
         | 
| 140 | 
            +
                terminate
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              def elapsed_microseconds(&blk)
         | 
| 144 | 
            +
                start = Time.now
         | 
| 145 | 
            +
                yield
         | 
| 146 | 
            +
                value = ((Time.now - start) * 1_000_000)
         | 
| 147 | 
            +
              end
         | 
| 148 | 
            +
            end
         | 
| 149 | 
            +
             | 
| 150 | 
            +
            threads = []
         | 
| 151 | 
            +
            receiver = transmitter = nil
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            threads << Thread.new do
         | 
| 154 | 
            +
              receiver = Receiver.new(link, message_size, roundtrip_count)
         | 
| 155 | 
            +
              receiver.run
         | 
| 156 | 
            +
            end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
            sleep 1
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            threads << Thread.new do
         | 
| 161 | 
            +
              transmitter = Transmitter.new(link, message_size, roundtrip_count)
         | 
| 162 | 
            +
              transmitter.run
         | 
| 163 | 
            +
            end
         | 
| 164 | 
            +
             | 
| 165 | 
            +
            set_signal_handler(receiver, transmitter)
         | 
| 166 | 
            +
             | 
| 167 | 
            +
            threads.each {|t| t.join}
         | 
    
        data/lib/nn-core/libnanomsg.rb
    CHANGED
    
    | @@ -33,25 +33,41 @@ module NNCore | |
| 33 33 | 
             
                # Size_t not working properly on Windows
         | 
| 34 34 | 
             
                find_type(:size_t) rescue typedef(:ulong, :size_t)
         | 
| 35 35 |  | 
| 36 | 
            +
                @blocking = true
         | 
| 36 37 | 
             
                attach_function :nn_version, [:pointer, :pointer, :pointer], :int
         | 
| 37 38 |  | 
| 39 | 
            +
                @blocking = true
         | 
| 38 40 | 
             
                attach_function :nn_errno, [], :int
         | 
| 41 | 
            +
                @blocking = true
         | 
| 39 42 | 
             
                attach_function :nn_strerror, [:int], :string
         | 
| 43 | 
            +
                @blocking = true
         | 
| 40 44 | 
             
                attach_function :nn_socket, [:int, :int], :int
         | 
| 45 | 
            +
                @blocking = true
         | 
| 41 46 | 
             
                attach_function :nn_close, [:int], :int
         | 
| 42 47 |  | 
| 48 | 
            +
                @blocking = true
         | 
| 43 49 | 
             
                attach_function :nn_getsockopt, [:int, :int, :int, :pointer, :pointer], :int
         | 
| 50 | 
            +
                @blocking = true
         | 
| 44 51 | 
             
                attach_function :nn_setsockopt, [:int, :int, :int, :pointer, :size_t], :int
         | 
| 52 | 
            +
                @blocking = true
         | 
| 45 53 | 
             
                attach_function :nn_bind, [:int, :string], :int
         | 
| 54 | 
            +
                @blocking = true
         | 
| 46 55 | 
             
                attach_function :nn_connect, [:int, :string], :int
         | 
| 56 | 
            +
                @blocking = true
         | 
| 47 57 | 
             
                attach_function :nn_shutdown, [:int, :int], :int
         | 
| 58 | 
            +
                @blocking = true
         | 
| 48 59 | 
             
                attach_function :nn_send, [:int, :pointer, :size_t, :int], :int
         | 
| 60 | 
            +
                @blocking = true
         | 
| 49 61 | 
             
                attach_function :nn_recv, [:int, :pointer, :size_t, :int], :int
         | 
| 50 62 |  | 
| 51 63 | 
             
                # functions for working with raw buffers
         | 
| 64 | 
            +
                @blocking = true
         | 
| 52 65 | 
             
                attach_function :nn_sendmsg, [:int, :pointer, :int], :int
         | 
| 66 | 
            +
                @blocking = true
         | 
| 53 67 | 
             
                attach_function :nn_recvmsg, [:int, :pointer, :int], :int
         | 
| 68 | 
            +
                @blocking = true
         | 
| 54 69 | 
             
                attach_function :nn_allocmsg, [:size_t, :int], :pointer
         | 
| 70 | 
            +
                @blocking = true
         | 
| 55 71 | 
             
                attach_function :nn_freemsg, [:pointer], :int        
         | 
| 56 72 | 
             
              end
         | 
| 57 73 | 
             
            end
         | 
    
        data/lib/nn-core/version.rb
    CHANGED
    
    
    
        data/spec/nn_connect_spec.rb
    CHANGED
    
    | @@ -53,35 +53,28 @@ module NNCore | |
| 53 53 | 
             
                      LibNanomsg.nn_errno.should == EINVAL
         | 
| 54 54 | 
             
                    end
         | 
| 55 55 |  | 
| 56 | 
            -
             | 
| 57 | 
            -
             | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 61 | 
            -
            #
         | 
| 62 | 
            -
            #        it "returns -1 for an invalid TCP address (non-numeric port)" do
         | 
| 63 | 
            -
            #          rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:port")
         | 
| 64 | 
            -
            #          rc.should == -1
         | 
| 65 | 
            -
            #          LibNanomsg.nn_errno.should == EINVAL
         | 
| 66 | 
            -
            #        end
         | 
| 67 | 
            -
            #
         | 
| 68 | 
            -
            #        it "returns -1 for an invalid TCP address (port number is out of range)" do
         | 
| 69 | 
            -
            #          rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:65536")
         | 
| 70 | 
            -
            #          rc.should == -1
         | 
| 71 | 
            -
            #          LibNanomsg.nn_errno.should == EINVAL
         | 
| 72 | 
            -
            #        end
         | 
| 56 | 
            +
                    it "returns -1 for an invalid TCP address (missing port)" do
         | 
| 57 | 
            +
                      rc = LibNanomsg.nn_connect(@socket, "tcp://*:")
         | 
| 58 | 
            +
                      rc.should == -1
         | 
| 59 | 
            +
                      LibNanomsg.nn_errno.should == EINVAL
         | 
| 60 | 
            +
                    end
         | 
| 73 61 |  | 
| 74 | 
            -
                    it "returns -1 for an  | 
| 75 | 
            -
                      rc = LibNanomsg.nn_connect(@socket, " | 
| 62 | 
            +
                    it "returns -1 for an invalid TCP address (non-numeric port)" do
         | 
| 63 | 
            +
                      rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:port")
         | 
| 76 64 | 
             
                      rc.should == -1
         | 
| 77 | 
            -
                      LibNanomsg.nn_errno.should ==  | 
| 65 | 
            +
                      LibNanomsg.nn_errno.should == EINVAL
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    it "returns -1 for an invalid TCP address (port number is out of range)" do
         | 
| 69 | 
            +
                      rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:65536")
         | 
| 70 | 
            +
                      rc.should == -1
         | 
| 71 | 
            +
                      LibNanomsg.nn_errno.should == EINVAL
         | 
| 78 72 | 
             
                    end
         | 
| 79 73 |  | 
| 80 | 
            -
                    it "returns -1 for  | 
| 81 | 
            -
                       | 
| 82 | 
            -
                      rc = LibNanomsg.nn_connect(@socket, "tcp://doesntexist:5555")
         | 
| 74 | 
            +
                    it "returns -1 for an unsupported transport protocol" do
         | 
| 75 | 
            +
                      rc = LibNanomsg.nn_connect(@socket, "zmq://192.168.0.1:65536")
         | 
| 83 76 | 
             
                      rc.should == -1
         | 
| 84 | 
            -
                      LibNanomsg.nn_errno.should ==  | 
| 77 | 
            +
                      LibNanomsg.nn_errno.should == EPROTONOSUPPORT
         | 
| 85 78 | 
             
                    end
         | 
| 86 79 |  | 
| 87 80 | 
             
                    it "returns 2 when connecting twice to an existing endpoint" do
         | 
    
        data/spec/nn_recv_spec.rb
    CHANGED
    
    | @@ -40,7 +40,10 @@ module NNCore | |
| 40 40 | 
             
                        buffer = FFI::MemoryPointer.new(:pointer)
         | 
| 41 41 | 
             
                        nbytes = LibNanomsg.nn_recv(@socket, buffer, NN_MSG, 0)
         | 
| 42 42 | 
             
                        nbytes.should == 3
         | 
| 43 | 
            -
                         | 
| 43 | 
            +
                        
         | 
| 44 | 
            +
                        # important to pass +nbytes+ to #read_string since the sent string
         | 
| 45 | 
            +
                        # is not null-terminated
         | 
| 46 | 
            +
                        buffer.get_pointer(0).read_string(nbytes).should == string
         | 
| 44 47 | 
             
                      end
         | 
| 45 48 | 
             
                    end
         | 
| 46 49 | 
             
                  end
         | 
    
        data/spec/nn_socket_spec.rb
    CHANGED
    
    | @@ -33,11 +33,10 @@ module NNCore | |
| 33 33 | 
             
                  end
         | 
| 34 34 |  | 
| 35 35 | 
             
                  context "given an unsupported address family" do
         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                     | 
| 40 | 
            -
                    #        end
         | 
| 36 | 
            +
                    it "nn_socket returns -1 and sets nn_errno to EAFNOSUPPORT" do
         | 
| 37 | 
            +
                      LibNanomsg.nn_socket(0, NN_PUB).should == -1
         | 
| 38 | 
            +
                      LibNanomsg.nn_errno.should == EAFNOSUPPORT
         | 
| 39 | 
            +
                    end
         | 
| 41 40 | 
             
                  end
         | 
| 42 41 |  | 
| 43 42 | 
             
                  context "given an unsupported protocol and a supported address family" do
         | 
    
        data/spec/nn_version_spec.rb
    CHANGED
    
    
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -6,7 +6,7 @@ module NNCore | |
| 6 6 | 
             
                :NN_LINGER => NN_LINGER,
         | 
| 7 7 | 
             
                :NN_SNDBUF => NN_SNDBUF,
         | 
| 8 8 | 
             
                :NN_RCVBUF => NN_RCVBUF,
         | 
| 9 | 
            -
                : | 
| 9 | 
            +
                :NN_SNDTIMEO => NN_SNDTIMEO,
         | 
| 10 10 | 
             
                :NN_RCVTIMEO => NN_RCVTIMEO,
         | 
| 11 11 | 
             
                :NN_RECONNECT_IVL => NN_RECONNECT_IVL,
         | 
| 12 12 | 
             
                :NN_RECONNECT_IVL_MAX => NN_RECONNECT_IVL_MAX,
         | 
    
        metadata
    CHANGED
    
    | @@ -1,64 +1,64 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: nn-core
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.1.6
         | 
| 4 5 | 
             
              prerelease: 
         | 
| 5 | 
            -
              version: 0.1.5
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| 8 8 | 
             
            - Chuck Remes
         | 
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013-02- | 
| 12 | 
            +
            date: 2013-02-20 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 | 
            -
               | 
| 16 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 15 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 17 16 | 
             
                requirements:
         | 
| 18 17 | 
             
                - - ! '>='
         | 
| 19 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 20 19 | 
             
                    version: '0'
         | 
| 21 20 | 
             
                none: false
         | 
| 22 21 | 
             
              type: :runtime
         | 
| 23 | 
            -
               | 
| 22 | 
            +
              name: ffi
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 24 25 | 
             
                requirements:
         | 
| 25 26 | 
             
                - - ! '>='
         | 
| 26 27 | 
             
                  - !ruby/object:Gem::Version
         | 
| 27 28 | 
             
                    version: '0'
         | 
| 28 29 | 
             
                none: false
         | 
| 29 | 
            -
              name: ffi
         | 
| 30 30 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 31 | 
            -
               | 
| 32 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 31 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 33 32 | 
             
                requirements:
         | 
| 34 33 | 
             
                - - ~>
         | 
| 35 34 | 
             
                  - !ruby/object:Gem::Version
         | 
| 36 35 | 
             
                    version: '2.6'
         | 
| 37 36 | 
             
                none: false
         | 
| 38 37 | 
             
              type: :development
         | 
| 39 | 
            -
               | 
| 38 | 
            +
              name: rspec
         | 
| 39 | 
            +
              prerelease: false
         | 
| 40 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 40 41 | 
             
                requirements:
         | 
| 41 42 | 
             
                - - ~>
         | 
| 42 43 | 
             
                  - !ruby/object:Gem::Version
         | 
| 43 44 | 
             
                    version: '2.6'
         | 
| 44 45 | 
             
                none: false
         | 
| 45 | 
            -
              name: rspec
         | 
| 46 46 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 47 | 
            -
               | 
| 48 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 47 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 49 48 | 
             
                requirements:
         | 
| 50 49 | 
             
                - - ! '>='
         | 
| 51 50 | 
             
                  - !ruby/object:Gem::Version
         | 
| 52 51 | 
             
                    version: '0'
         | 
| 53 52 | 
             
                none: false
         | 
| 54 53 | 
             
              type: :development
         | 
| 55 | 
            -
               | 
| 54 | 
            +
              name: rake
         | 
| 55 | 
            +
              prerelease: false
         | 
| 56 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 56 57 | 
             
                requirements:
         | 
| 57 58 | 
             
                - - ! '>='
         | 
| 58 59 | 
             
                  - !ruby/object:Gem::Version
         | 
| 59 60 | 
             
                    version: '0'
         | 
| 60 61 | 
             
                none: false
         | 
| 61 | 
            -
              name: rake
         | 
| 62 62 | 
             
            description: ! 'Wraps the nanomsg networking library using the ruby FFI (foreign
         | 
| 63 63 |  | 
| 64 64 | 
             
              function interface). It only exposes the native C API to Ruby. Other gems should
         | 
| @@ -85,6 +85,8 @@ files: | |
| 85 85 | 
             
              UkVBRE1FLm1k
         | 
| 86 86 | 
             
            - !binary |-
         | 
| 87 87 | 
             
              UmFrZWZpbGU=
         | 
| 88 | 
            +
            - !binary |-
         | 
| 89 | 
            +
              ZXhhbXBsZXMvcm91bmR0cmlwX2xhdGVuY3kucmI=
         | 
| 88 90 | 
             
            - !binary |-
         | 
| 89 91 | 
             
              bGliL25uLWNvcmUucmI=
         | 
| 90 92 | 
             
            - !binary |-
         |