kyototycoon 0.1.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|