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
|