kyototycoon 0.1.2 → 0.5.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.
- data/README.markdown +29 -7
- data/benchmark/bulk.rb +3 -25
- data/benchmark/bulk_bigdata.rb +2 -15
- data/benchmark/getset.rb +2 -27
- data/benchmark/getset_while_1sec.rb +2 -14
- data/benchmark/helper.rb +22 -0
- data/kyototycoon.gemspec +3 -4
- data/lib/kyototycoon.rb +56 -27
- data/lib/kyototycoon/tsvrpc.rb +1 -23
- data/lib/kyototycoon/tsvrpc/skinny.rb +16 -8
- data/spec/helper.rb +3 -0
- metadata +5 -6
- data/benchmark/agent.rb +0 -27
- data/lib/kyototycoon/tsvrpc/nethttp.rb +0 -28
    
        data/README.markdown
    CHANGED
    
    | @@ -1,3 +1,12 @@ | |
| 1 | 
            +
            KyotoTycoon client for Ruby.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Feature / Fixture
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Always Keep-Alive connect (v0.5.0+)
         | 
| 6 | 
            +
            * You can choise key/value encoding from URI or Base64
         | 
| 7 | 
            +
            * You can use MessagePack tranparency
         | 
| 8 | 
            +
            * Benchmark scripts appended(they are connect to localhost:19999)
         | 
| 9 | 
            +
             | 
| 1 10 | 
             
            # Install
         | 
| 2 11 |  | 
| 3 12 | 
             
                $ gem install kyototycoon
         | 
| @@ -6,7 +15,7 @@ | |
| 6 15 |  | 
| 7 16 | 
             
            ## Simple case
         | 
| 8 17 |  | 
| 9 | 
            -
                @kt = KyotoTycoon.new
         | 
| 18 | 
            +
                @kt = KyotoTycoon.new('localhost', 1978)
         | 
| 10 19 |  | 
| 11 20 | 
             
                # traditional style
         | 
| 12 21 | 
             
                @kt.set('foo', 123)
         | 
| @@ -21,9 +30,18 @@ | |
| 21 30 |  | 
| 22 31 |  | 
| 23 32 | 
             
            ## Complex case
         | 
| 33 | 
            +
                # KT#configure for instance setting store.
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                KyotoTycoon.configure(:generic) do |kt|
         | 
| 36 | 
            +
                  kt.db = '*' # on memory
         | 
| 37 | 
            +
                end
         | 
| 24 38 |  | 
| 25 | 
            -
                 | 
| 26 | 
            -
                 | 
| 39 | 
            +
                # connect any host, any port
         | 
| 40 | 
            +
                KyotoTycoon.configure(:favicon, 'remotehost', 12345) do |kt|
         | 
| 41 | 
            +
                  kt.db = 'favicons.kch' # DB file as KT known
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                @kt = KyotoTycoon.create(:generic) # got KT instance by KT#configure(:generic) rules
         | 
| 27 45 |  | 
| 28 46 | 
             
                # set/bulk_set/get/bulk_get uses msgpack. default as :default
         | 
| 29 47 | 
             
                @kt.serializer = :msgpack
         | 
| @@ -37,14 +55,14 @@ | |
| 37 55 | 
             
                # @kt.logger = STDOUT
         | 
| 38 56 | 
             
                # @kt.logger = Logger.new(STDOUT)
         | 
| 39 57 |  | 
| 40 | 
            -
                # HTTP agent
         | 
| 41 | 
            -
                @kt.agent = :skinny # low-level socket communicate. a bit of faster than :nethttp(default). try benchmark/agent.rb
         | 
| 42 | 
            -
             | 
| 43 58 | 
             
                # standby server
         | 
| 44 59 | 
             
                @kt.connect_timeout = 0.5 # => wait 0.5 sec for connection open
         | 
| 45 60 | 
             
                @kt.servers << ['server2', 1978] # standby server that will use when primary server (a.k.a. KT#new(host, port)) is dead.
         | 
| 46 61 | 
             
                @kt.servers << ['server3', 1978] # same as above
         | 
| 47 62 |  | 
| 63 | 
            +
                # key/value encoding from :U or :B(default). default as base64 because it seems better than URL encode for me.
         | 
| 64 | 
            +
                @kt.colenc = :U
         | 
| 65 | 
            +
             | 
| 48 66 | 
             
                # get/set
         | 
| 49 67 | 
             
                @kt.set('foo', 42, 100) # => expire at 100 seconds after
         | 
| 50 68 | 
             
                @kt['foo'] # => 42. it is interger by msgpack serializer works
         | 
| @@ -61,7 +79,7 @@ | |
| 61 79 | 
             
                @kt.remove_bulk([:foo, :bar])
         | 
| 62 80 |  | 
| 63 81 | 
             
                # it can store when msgpack using.
         | 
| 64 | 
            -
                @kt['baz'] = {'a' => 'a', 'b' => 'b}
         | 
| 82 | 
            +
                @kt['baz'] = {'a' => 'a', 'b' => 'b'}
         | 
| 65 83 | 
             
                @kt['baz'] # => {'a' => 'a', 'b' => 'b}
         | 
| 66 84 |  | 
| 67 85 | 
             
                # increment
         | 
| @@ -70,6 +88,10 @@ | |
| 70 88 | 
             
                @kt.increment('bar', 10) # => 12
         | 
| 71 89 | 
             
                @kt.increment('bar', -5) # => 7
         | 
| 72 90 |  | 
| 91 | 
            +
                # shorthand
         | 
| 92 | 
            +
                @kt.incr('foo') # => 1
         | 
| 93 | 
            +
                @kt.decr('foo') # => 0
         | 
| 94 | 
            +
             | 
| 73 95 | 
             
                # delete keys
         | 
| 74 96 | 
             
                @kt.delete(:foo, :bar, :baz)
         | 
| 75 97 |  | 
    
        data/benchmark/bulk.rb
    CHANGED
    
    | @@ -1,11 +1,7 @@ | |
| 1 1 | 
             
            # -- coding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
            require "rubygems"
         | 
| 5 | 
            -
            require "benchmark"
         | 
| 6 | 
            -
            require 'kyototycoon.rb'
         | 
| 3 | 
            +
            require File.expand_path("#{File.dirname(__FILE__)}/helper.rb")
         | 
| 7 4 |  | 
| 8 | 
            -
            kt = KyotoTycoon.new
         | 
| 9 5 | 
             
            bulk={}
         | 
| 10 6 | 
             
            50000.times.map{|n|
         | 
| 11 7 | 
             
              bulk[n.to_s] = "#{n}-#{rand}"
         | 
| @@ -15,23 +11,5 @@ job = lambda {|kt| | |
| 15 11 | 
             
              kt.get_bulk(bulk.keys)
         | 
| 16 12 | 
             
              kt.clear
         | 
| 17 13 | 
             
            }
         | 
| 18 | 
            -
             | 
| 19 | 
            -
             | 
| 20 | 
            -
                kt.serializer=:default
         | 
| 21 | 
            -
                job.call(kt)
         | 
| 22 | 
            -
              }
         | 
| 23 | 
            -
              x.report('msgpack') {
         | 
| 24 | 
            -
                kt.serializer=:msgpack
         | 
| 25 | 
            -
                job.call(kt)
         | 
| 26 | 
            -
              }
         | 
| 27 | 
            -
              x.report('default(skinny)') {
         | 
| 28 | 
            -
                kt.agent = :skinny
         | 
| 29 | 
            -
                kt.serializer=:default
         | 
| 30 | 
            -
                job.call(kt)
         | 
| 31 | 
            -
              }
         | 
| 32 | 
            -
              x.report('msgpack(skinny)') {
         | 
| 33 | 
            -
                kt.agent = :skinny
         | 
| 34 | 
            -
                kt.serializer=:msgpack
         | 
| 35 | 
            -
                job.call(kt)
         | 
| 36 | 
            -
              }
         | 
| 37 | 
            -
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            benchmark(job)
         | 
    
        data/benchmark/bulk_bigdata.rb
    CHANGED
    
    | @@ -1,11 +1,7 @@ | |
| 1 1 | 
             
            # -- coding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
            require "rubygems"
         | 
| 5 | 
            -
            require "benchmark"
         | 
| 6 | 
            -
            require 'kyototycoon.rb'
         | 
| 3 | 
            +
            require File.expand_path("#{File.dirname(__FILE__)}/helper.rb")
         | 
| 7 4 |  | 
| 8 | 
            -
            kt = KyotoTycoon.new
         | 
| 9 5 | 
             
            bulk={}
         | 
| 10 6 | 
             
            str = "string ああ" * 10000
         | 
| 11 7 | 
             
            100.times.map{|n|
         | 
| @@ -16,13 +12,4 @@ job = lambda {|kt| | |
| 16 12 | 
             
              kt.get_bulk(bulk.keys)
         | 
| 17 13 | 
             
              kt.clear
         | 
| 18 14 | 
             
            }
         | 
| 19 | 
            -
             | 
| 20 | 
            -
              x.report('default') {
         | 
| 21 | 
            -
                kt.serializer=:default
         | 
| 22 | 
            -
                job.call(kt)
         | 
| 23 | 
            -
              }
         | 
| 24 | 
            -
              x.report('msgpack') {
         | 
| 25 | 
            -
                kt.serializer=:msgpack
         | 
| 26 | 
            -
                job.call(kt)
         | 
| 27 | 
            -
              }
         | 
| 28 | 
            -
            end
         | 
| 15 | 
            +
            benchmark(job)
         | 
    
        data/benchmark/getset.rb
    CHANGED
    
    | @@ -1,11 +1,7 @@ | |
| 1 1 | 
             
            # -- coding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            require " | 
| 4 | 
            -
            require "benchmark"
         | 
| 5 | 
            -
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 6 | 
            -
            require 'kyoto_tycoon.rb'
         | 
| 3 | 
            +
            require File.expand_path("#{File.dirname(__FILE__)}/helper.rb")
         | 
| 7 4 |  | 
| 8 | 
            -
            kt = KyotoTycoon.new
         | 
| 9 5 | 
             
            job = lambda {|kt|
         | 
| 10 6 | 
             
              1000.times{|n|
         | 
| 11 7 | 
             
                kt.set(n.to_s, n)
         | 
| @@ -13,25 +9,4 @@ job = lambda {|kt| | |
| 13 9 | 
             
              }
         | 
| 14 10 | 
             
              kt.clear
         | 
| 15 11 | 
             
            }
         | 
| 16 | 
            -
             | 
| 17 | 
            -
              x.report('default') {
         | 
| 18 | 
            -
                kt.agent = :nethttp
         | 
| 19 | 
            -
                kt.serializer=:default
         | 
| 20 | 
            -
                job.call(kt)
         | 
| 21 | 
            -
              }
         | 
| 22 | 
            -
              x.report('msgpack') {
         | 
| 23 | 
            -
                kt.agent = :nethttp
         | 
| 24 | 
            -
                kt.serializer=:msgpack
         | 
| 25 | 
            -
                job.call(kt)
         | 
| 26 | 
            -
              }
         | 
| 27 | 
            -
              x.report('default(skinny)') {
         | 
| 28 | 
            -
                kt.agent = :skinny
         | 
| 29 | 
            -
                kt.serializer=:default
         | 
| 30 | 
            -
                job.call(kt)
         | 
| 31 | 
            -
              }
         | 
| 32 | 
            -
              x.report('msgpack(skinny)') {
         | 
| 33 | 
            -
                kt.agent = :skinny
         | 
| 34 | 
            -
                kt.serializer=:msgpack
         | 
| 35 | 
            -
                job.call(kt)
         | 
| 36 | 
            -
              }
         | 
| 37 | 
            -
            end
         | 
| 12 | 
            +
            benchmark(job)
         | 
| @@ -1,10 +1,6 @@ | |
| 1 1 | 
             
            # -- coding: utf-8
         | 
| 2 2 |  | 
| 3 | 
            -
            require " | 
| 4 | 
            -
            require "benchmark"
         | 
| 5 | 
            -
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 6 | 
            -
            require "msgpack"
         | 
| 7 | 
            -
            require 'kyototycoon.rb'
         | 
| 3 | 
            +
            require File.expand_path("#{File.dirname(__FILE__)}/helper.rb")
         | 
| 8 4 |  | 
| 9 5 | 
             
            job = lambda {|kt|
         | 
| 10 6 | 
             
              cnt = 0
         | 
| @@ -22,12 +18,4 @@ job = lambda {|kt| | |
| 22 18 | 
             
              cnt
         | 
| 23 19 | 
             
            }
         | 
| 24 20 |  | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
            %w"nethttp skinny".each{|agent|
         | 
| 28 | 
            -
              %w!default msgpack!.each{|serializer|
         | 
| 29 | 
            -
                kt.agent = agent.to_sym
         | 
| 30 | 
            -
                kt.serializer = serializer.to_sym
         | 
| 31 | 
            -
                puts "#{agent}/#{serializer}: #{job.call(kt)}"
         | 
| 32 | 
            -
              }
         | 
| 33 | 
            -
            }
         | 
| 21 | 
            +
            benchmark(job)
         | 
    
        data/benchmark/helper.rb
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # -- coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "benchmark"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 6 | 
            +
            require 'kyototycoon.rb'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            def benchmark(job)
         | 
| 9 | 
            +
              kt = KyotoTycoon.new('0.0.0.0', 19999)
         | 
| 10 | 
            +
              Benchmark.bm do |x|
         | 
| 11 | 
            +
                %w!B U!.each{|colenc|
         | 
| 12 | 
            +
                  %w!default msgpack!.each{|serializer|
         | 
| 13 | 
            +
                    x.report("#{serializer}, colenc=#{colenc}") {
         | 
| 14 | 
            +
                      kt.serializer=serializer.to_sym
         | 
| 15 | 
            +
                      kt.colenc = colenc.to_sym
         | 
| 16 | 
            +
                      job.call(kt)
         | 
| 17 | 
            +
                    }
         | 
| 18 | 
            +
                  }
         | 
| 19 | 
            +
                }
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
    
        data/kyototycoon.gemspec
    CHANGED
    
    | @@ -5,11 +5,11 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |s|
         | 
| 7 7 | 
             
              s.name = %q{kyototycoon}
         | 
| 8 | 
            -
              s.version = "0. | 
| 8 | 
            +
              s.version = "0.5.0"
         | 
| 9 9 |  | 
| 10 10 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 11 | 
             
              s.authors = ["uu59"]
         | 
| 12 | 
            -
              s.date = %q{2010-12- | 
| 12 | 
            +
              s.date = %q{2010-12-22}
         | 
| 13 13 | 
             
              s.description = %q{KyotoTycoon client for Ruby}
         | 
| 14 14 | 
             
              s.email = %q{a@tt25.org}
         | 
| 15 15 | 
             
              s.extra_rdoc_files = [
         | 
| @@ -22,7 +22,7 @@ Gem::Specification.new do |s| | |
| 22 22 | 
             
                "README.markdown",
         | 
| 23 23 | 
             
                "Rakefile",
         | 
| 24 24 | 
             
                "VERSION",
         | 
| 25 | 
            -
                "benchmark/ | 
| 25 | 
            +
                "benchmark/helper.rb",
         | 
| 26 26 | 
             
                "benchmark/bulk.rb",
         | 
| 27 27 | 
             
                "benchmark/bulk_bigdata.rb",
         | 
| 28 28 | 
             
                "benchmark/getset.rb",
         | 
| @@ -33,7 +33,6 @@ Gem::Specification.new do |s| | |
| 33 33 | 
             
                "lib/kyototycoon/serializer/default.rb",
         | 
| 34 34 | 
             
                "lib/kyototycoon/serializer/msgpack.rb",
         | 
| 35 35 | 
             
                "lib/kyototycoon/tsvrpc.rb",
         | 
| 36 | 
            -
                "lib/kyototycoon/tsvrpc/nethttp.rb",
         | 
| 37 36 | 
             
                "lib/kyototycoon/tsvrpc/skinny.rb",
         | 
| 38 37 | 
             
                "spec/helper.rb"
         | 
| 39 38 | 
             
              ]
         | 
    
        data/lib/kyototycoon.rb
    CHANGED
    
    | @@ -10,9 +10,10 @@ require "kyototycoon/serializer/default.rb" | |
| 10 10 | 
             
            require "kyototycoon/serializer/msgpack.rb"
         | 
| 11 11 | 
             
            require "kyototycoon/tsvrpc.rb"
         | 
| 12 12 | 
             
            require "kyototycoon/tsvrpc/skinny.rb"
         | 
| 13 | 
            -
            require "kyototycoon/tsvrpc/nethttp.rb"
         | 
| 14 13 |  | 
| 15 14 | 
             
            class KyotoTycoon
         | 
| 15 | 
            +
              VERSION = '0.5.0'
         | 
| 16 | 
            +
             | 
| 16 17 | 
             
              attr_accessor :colenc, :connect_timeout, :servers
         | 
| 17 18 | 
             
              attr_reader :serializer, :logger, :db
         | 
| 18 19 |  | 
| @@ -42,8 +43,7 @@ class KyotoTycoon | |
| 42 43 | 
             
                @servers = [[host, port]]
         | 
| 43 44 | 
             
                @serializer = KyotoTycoon::Serializer::Default
         | 
| 44 45 | 
             
                @logger = Logger.new(nil)
         | 
| 45 | 
            -
                @ | 
| 46 | 
            -
                @colenc = :U
         | 
| 46 | 
            +
                @colenc = :B
         | 
| 47 47 | 
             
                @connect_timeout = 0.5
         | 
| 48 48 | 
             
              end
         | 
| 49 49 |  | 
| @@ -63,10 +63,6 @@ class KyotoTycoon | |
| 63 63 | 
             
                @logger = logger
         | 
| 64 64 | 
             
              end
         | 
| 65 65 |  | 
| 66 | 
            -
              def agent=(agent)
         | 
| 67 | 
            -
                @agent = agent
         | 
| 68 | 
            -
              end
         | 
| 69 | 
            -
             | 
| 70 66 | 
             
              def get(key)
         | 
| 71 67 | 
             
                res = request('/rpc/get', {:key => key})
         | 
| 72 68 | 
             
                @serializer.decode(Tsvrpc.parse(res[:body])['value'])
         | 
| @@ -218,35 +214,39 @@ class KyotoTycoon | |
| 218 214 | 
             
                  params ||= {}
         | 
| 219 215 | 
             
                  params[:DB] = @db
         | 
| 220 216 | 
             
                end
         | 
| 221 | 
            -
             | 
| 222 | 
            -
             | 
| 223 | 
            -
             | 
| 224 | 
            -
             | 
| 225 | 
            -
                      @servers = [[host, port]]
         | 
| 226 | 
            -
                      break
         | 
| 227 | 
            -
                    end
         | 
| 228 | 
            -
                  }
         | 
| 229 | 
            -
                end
         | 
| 230 | 
            -
                if @servers.length == 0
         | 
| 231 | 
            -
                  msg = "alived server not exists"
         | 
| 232 | 
            -
                  @logger.crit(msg)
         | 
| 233 | 
            -
                  raise msg
         | 
| 234 | 
            -
                end
         | 
| 235 | 
            -
                tsvrpc ||= begin
         | 
| 236 | 
            -
                  host, port = *@servers.first
         | 
| 237 | 
            -
                  Tsvrpc.new(host, port)
         | 
| 217 | 
            +
             | 
| 218 | 
            +
                status,body = client.request(path, params, @colenc)
         | 
| 219 | 
            +
                if ![200, 450].include?(status.to_i)
         | 
| 220 | 
            +
                  raise body
         | 
| 238 221 | 
             
                end
         | 
| 239 | 
            -
                res =  | 
| 222 | 
            +
                res = {:status => status, :body => body}
         | 
| 240 223 | 
             
                @logger.info("#{path}: #{res[:status]} with query parameters #{params.inspect}")
         | 
| 241 224 | 
             
                res
         | 
| 242 225 | 
             
              end
         | 
| 243 226 |  | 
| 227 | 
            +
              def client
         | 
| 228 | 
            +
                host, port = *choice_server
         | 
| 229 | 
            +
                @client ||= begin
         | 
| 230 | 
            +
                  Tsvrpc::Skinny.new(host, port)
         | 
| 231 | 
            +
                end
         | 
| 232 | 
            +
              end
         | 
| 233 | 
            +
             | 
| 234 | 
            +
              def start
         | 
| 235 | 
            +
                client.start
         | 
| 236 | 
            +
              end
         | 
| 237 | 
            +
             | 
| 238 | 
            +
              def finish
         | 
| 239 | 
            +
                client.finish
         | 
| 240 | 
            +
              end
         | 
| 241 | 
            +
             | 
| 242 | 
            +
              private
         | 
| 243 | 
            +
             | 
| 244 244 | 
             
              def ping(host, port)
         | 
| 245 245 | 
             
                begin
         | 
| 246 | 
            +
                  rpc = Tsvrpc::Skinny.new(host, port)
         | 
| 246 247 | 
             
                  timeout(@connect_timeout){
         | 
| 247 248 | 
             
                    @logger.debug("connect check #{host}:#{port}")
         | 
| 248 | 
            -
                     | 
| 249 | 
            -
                    res = rpc.request('/rpc/echo', {'0' => '0'}, :skinny, :U)
         | 
| 249 | 
            +
                    res = rpc.request('/rpc/echo', {'0' => '0'}, :U)
         | 
| 250 250 | 
             
                    @logger.debug(res)
         | 
| 251 251 | 
             
                  }
         | 
| 252 252 | 
             
                  true
         | 
| @@ -254,9 +254,38 @@ class KyotoTycoon | |
| 254 254 | 
             
                  # Ruby 1.8.7 compatible
         | 
| 255 255 | 
             
                  @logger.warn("connect failed at #{host}:#{port}")
         | 
| 256 256 | 
             
                  false
         | 
| 257 | 
            +
                rescue SystemCallError
         | 
| 258 | 
            +
                  @logger.warn("connect failed at #{host}:#{port}")
         | 
| 259 | 
            +
                  false
         | 
| 257 260 | 
             
                rescue => ex
         | 
| 258 261 | 
             
                  @logger.warn("connect failed at #{host}:#{port}")
         | 
| 259 262 | 
             
                  false
         | 
| 263 | 
            +
                ensure
         | 
| 264 | 
            +
                  rpc.finish
         | 
| 260 265 | 
             
                end
         | 
| 261 266 | 
             
              end
         | 
| 267 | 
            +
             | 
| 268 | 
            +
              def choice_server
         | 
| 269 | 
            +
                current = @servers.first
         | 
| 270 | 
            +
                if @servers.length > 1
         | 
| 271 | 
            +
                  @servers.each{|s|
         | 
| 272 | 
            +
                    host,port = *s
         | 
| 273 | 
            +
                    if ping(host, port)
         | 
| 274 | 
            +
                      @servers = [[host, port]]
         | 
| 275 | 
            +
                      break
         | 
| 276 | 
            +
                    end
         | 
| 277 | 
            +
                  }
         | 
| 278 | 
            +
                end
         | 
| 279 | 
            +
                if @servers.length == 0
         | 
| 280 | 
            +
                  msg = "alived server not exists"
         | 
| 281 | 
            +
                  @logger.crit(msg)
         | 
| 282 | 
            +
                  raise msg
         | 
| 283 | 
            +
                end
         | 
| 284 | 
            +
                result = @servers.first
         | 
| 285 | 
            +
                if current != result
         | 
| 286 | 
            +
                  @client = nil
         | 
| 287 | 
            +
                end
         | 
| 288 | 
            +
                result
         | 
| 289 | 
            +
              end
         | 
| 290 | 
            +
             | 
| 262 291 | 
             
            end
         | 
    
        data/lib/kyototycoon/tsvrpc.rb
    CHANGED
    
    | @@ -2,29 +2,7 @@ | |
| 2 2 |  | 
| 3 3 |  | 
| 4 4 | 
             
            class KyotoTycoon
         | 
| 5 | 
            -
               | 
| 6 | 
            -
                def initialize(host, port)
         | 
| 7 | 
            -
                  @host = host
         | 
| 8 | 
            -
                  @port = port
         | 
| 9 | 
            -
                end
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                def http(agent)
         | 
| 12 | 
            -
                  case agent
         | 
| 13 | 
            -
                    when :skinny
         | 
| 14 | 
            -
                      Skinny.new(@host, @port)
         | 
| 15 | 
            -
                    else
         | 
| 16 | 
            -
                      Nethttp.new(@host, @port)
         | 
| 17 | 
            -
                  end
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
                def request(path, params, agent, colenc)
         | 
| 21 | 
            -
                  status,body = *http(agent).request(path, params, colenc)
         | 
| 22 | 
            -
                  if ![200, 450].include?(status)
         | 
| 23 | 
            -
                    raise body
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
                  {:status => status, :body => body}
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
             | 
| 5 | 
            +
              module Tsvrpc
         | 
| 28 6 | 
             
                def self.parse(body)
         | 
| 29 7 | 
             
                  body.split("\n").inject({}){|r, line|
         | 
| 30 8 | 
             
                    k,v = *line.split("\t", 2).map{|v| CGI.unescape(v)}
         | 
| @@ -1,28 +1,29 @@ | |
| 1 1 | 
             
            # -- coding: utf-8
         | 
| 2 2 |  | 
| 3 3 | 
             
            class KyotoTycoon
         | 
| 4 | 
            -
               | 
| 4 | 
            +
              module Tsvrpc
         | 
| 5 5 | 
             
                class Skinny
         | 
| 6 6 | 
             
                  def initialize(host, port)
         | 
| 7 7 | 
             
                    @host = host
         | 
| 8 8 | 
             
                    @port = port
         | 
| 9 9 | 
             
                    @tpl = ""
         | 
| 10 | 
            -
                    @tpl << "POST %s HTTP/1. | 
| 10 | 
            +
                    @tpl << "POST %s HTTP/1.1\r\n"
         | 
| 11 11 | 
             
                    @tpl << "Content-Length: %d\r\n"
         | 
| 12 12 | 
             
                    @tpl << "Content-Type: text/tab-separated-values; colenc=%s\r\n"
         | 
| 13 13 | 
             
                    @tpl << "\r\n%s"
         | 
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 16 | 
             
                  def request(path, params, colenc)
         | 
| 17 | 
            -
                     | 
| 17 | 
            +
                    start 
         | 
| 18 18 | 
             
                    query = KyotoTycoon::Tsvrpc.build_query(params, colenc)
         | 
| 19 19 | 
             
                    request = @tpl % [path, query.bytesize, colenc, query]
         | 
| 20 | 
            -
                    sock.write(request)
         | 
| 21 | 
            -
                     | 
| 20 | 
            +
                    @sock.write(request)
         | 
| 21 | 
            +
                    first_line = @sock.gets
         | 
| 22 | 
            +
                    status = first_line[9, 3]
         | 
| 22 23 | 
             
                    bodylen = 0
         | 
| 23 24 | 
             
                    body = ""
         | 
| 24 25 | 
             
                    loop do
         | 
| 25 | 
            -
                      line = sock.gets
         | 
| 26 | 
            +
                      line = @sock.gets
         | 
| 26 27 | 
             
                      if line['Content-Length']
         | 
| 27 28 | 
             
                        bodylen = line.match(/[0-9]+/)[0].to_i
         | 
| 28 29 | 
             
                        next
         | 
| @@ -31,10 +32,17 @@ class KyotoTycoon | |
| 31 32 | 
             
                        break
         | 
| 32 33 | 
             
                      end
         | 
| 33 34 | 
             
                    end
         | 
| 34 | 
            -
                    body = sock.read(bodylen)
         | 
| 35 | 
            -
                    sock.close
         | 
| 35 | 
            +
                    body = @sock.read(bodylen)
         | 
| 36 36 | 
             
                    [status.to_i, body]
         | 
| 37 37 | 
             
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def start
         | 
| 40 | 
            +
                    @sock ||= ::TCPSocket.new(@host, @port)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def finish
         | 
| 44 | 
            +
                    @sock.close if @sock
         | 
| 45 | 
            +
                  end
         | 
| 38 46 | 
             
                end
         | 
| 39 47 | 
             
              end
         | 
| 40 48 | 
             
            end
         | 
    
        data/spec/helper.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version | |
| 4 4 | 
             
              prerelease: false
         | 
| 5 5 | 
             
              segments: 
         | 
| 6 6 | 
             
              - 0
         | 
| 7 | 
            -
              -  | 
| 8 | 
            -
              -  | 
| 9 | 
            -
              version: 0. | 
| 7 | 
            +
              - 5
         | 
| 8 | 
            +
              - 0
         | 
| 9 | 
            +
              version: 0.5.0
         | 
| 10 10 | 
             
            platform: ruby
         | 
| 11 11 | 
             
            authors: 
         | 
| 12 12 | 
             
            - uu59
         | 
| @@ -14,7 +14,7 @@ autorequire: | |
| 14 14 | 
             
            bindir: bin
         | 
| 15 15 | 
             
            cert_chain: []
         | 
| 16 16 |  | 
| 17 | 
            -
            date: 2010-12- | 
| 17 | 
            +
            date: 2010-12-22 00:00:00 +09:00
         | 
| 18 18 | 
             
            default_executable: 
         | 
| 19 19 | 
             
            dependencies: 
         | 
| 20 20 | 
             
            - !ruby/object:Gem::Dependency 
         | 
| @@ -103,7 +103,7 @@ files: | |
| 103 103 | 
             
            - README.markdown
         | 
| 104 104 | 
             
            - Rakefile
         | 
| 105 105 | 
             
            - VERSION
         | 
| 106 | 
            -
            - benchmark/ | 
| 106 | 
            +
            - benchmark/helper.rb
         | 
| 107 107 | 
             
            - benchmark/bulk.rb
         | 
| 108 108 | 
             
            - benchmark/bulk_bigdata.rb
         | 
| 109 109 | 
             
            - benchmark/getset.rb
         | 
| @@ -114,7 +114,6 @@ files: | |
| 114 114 | 
             
            - lib/kyototycoon/serializer/default.rb
         | 
| 115 115 | 
             
            - lib/kyototycoon/serializer/msgpack.rb
         | 
| 116 116 | 
             
            - lib/kyototycoon/tsvrpc.rb
         | 
| 117 | 
            -
            - lib/kyototycoon/tsvrpc/nethttp.rb
         | 
| 118 117 | 
             
            - lib/kyototycoon/tsvrpc/skinny.rb
         | 
| 119 118 | 
             
            - spec/helper.rb
         | 
| 120 119 | 
             
            has_rdoc: true
         | 
    
        data/benchmark/agent.rb
    DELETED
    
    | @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            # -- coding: utf-8
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require "rubygems"
         | 
| 4 | 
            -
            require "benchmark"
         | 
| 5 | 
            -
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 6 | 
            -
            require 'kyototycoon.rb'
         | 
| 7 | 
            -
             | 
| 8 | 
            -
            kt = KyotoTycoon.new
         | 
| 9 | 
            -
            job = lambda {|kt|
         | 
| 10 | 
            -
              10000.times{|n|
         | 
| 11 | 
            -
                kt.set(n.to_s, n)
         | 
| 12 | 
            -
                kt.get(n)
         | 
| 13 | 
            -
              }
         | 
| 14 | 
            -
              kt.clear
         | 
| 15 | 
            -
            }
         | 
| 16 | 
            -
            Benchmark.bm do |x|
         | 
| 17 | 
            -
              x.report('skinny') {
         | 
| 18 | 
            -
                kt.agent = :skinny
         | 
| 19 | 
            -
                kt.serializer=:default
         | 
| 20 | 
            -
                job.call(kt)
         | 
| 21 | 
            -
              }
         | 
| 22 | 
            -
              x.report('nethttp') {
         | 
| 23 | 
            -
                kt.agent = :nethttp
         | 
| 24 | 
            -
                kt.serializer=:default
         | 
| 25 | 
            -
                job.call(kt)
         | 
| 26 | 
            -
              }
         | 
| 27 | 
            -
            end
         | 
| @@ -1,28 +0,0 @@ | |
| 1 | 
            -
            # -- coding: utf-8
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            require "rubygems"
         | 
| 4 | 
            -
             | 
| 5 | 
            -
            class KyotoTycoon
         | 
| 6 | 
            -
              class Tsvrpc
         | 
| 7 | 
            -
                class Nethttp
         | 
| 8 | 
            -
                  def initialize(host, port)
         | 
| 9 | 
            -
                    @host = host
         | 
| 10 | 
            -
                    @port = port
         | 
| 11 | 
            -
                    @http ||= ::Net::HTTP.new(@host, @port)
         | 
| 12 | 
            -
                  end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
                  def request(path, params, colenc)
         | 
| 15 | 
            -
                    query = KyotoTycoon::Tsvrpc.build_query(params, colenc)
         | 
| 16 | 
            -
                    req = Net::HTTP::Post.new(path)
         | 
| 17 | 
            -
                    if query.length > 0
         | 
| 18 | 
            -
                      req.body = query
         | 
| 19 | 
            -
                      req['Content-Length'] = query.size
         | 
| 20 | 
            -
                    end
         | 
| 21 | 
            -
                    req['Content-Type'] = "text/tab-separated-values; colenc=#{colenc}"
         | 
| 22 | 
            -
                    req['Connection'] = "close"
         | 
| 23 | 
            -
                    res = @http.request(req)
         | 
| 24 | 
            -
                    [res.code.to_i, res.body]
         | 
| 25 | 
            -
                  end
         | 
| 26 | 
            -
                end
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
            end
         |