flare-tools 0.1.4 → 0.4.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Flare-tools.txt +0 -0
- data/History.txt +114 -2
- data/LICENSE +21 -0
- data/Manifest.txt +65 -8
- data/README.txt +356 -0
- data/Rakefile +90 -25
- data/Tutorial.txt +370 -0
- data/bin/flare-admin +6 -0
- data/bin/flare-argv0 +6 -0
- data/bin/flare-deploy +6 -0
- data/bin/flare-keychecker +6 -0
- data/bin/flare-part +6 -0
- data/bin/flare-ping +6 -0
- data/bin/flare-stats +4 -10
- data/bin/flare-zkadmin +6 -0
- data/lib/flare/net/connection.rb +98 -0
- data/lib/flare/test/cluster.rb +140 -0
- data/lib/flare/test/daemon.rb +144 -0
- data/lib/flare/test/node.rb +62 -0
- data/lib/flare/tools.rb +18 -16
- data/lib/flare/tools/cli.rb +32 -0
- data/lib/flare/tools/cli/activate.rb +106 -0
- data/lib/flare/tools/cli/balance.rb +83 -0
- data/lib/flare/tools/cli/cli_util.rb +77 -0
- data/lib/flare/tools/cli/deploy.rb +170 -0
- data/lib/flare/tools/cli/down.rb +85 -0
- data/lib/flare/tools/cli/dump.rb +219 -0
- data/lib/flare/tools/cli/dumpkey.rb +117 -0
- data/lib/flare/tools/cli/flare_admin.rb +81 -0
- data/lib/flare/tools/cli/flare_argv0.rb +60 -0
- data/lib/flare/tools/cli/flare_keychecker.rb +106 -0
- data/lib/flare/tools/cli/flare_zkadmin.rb +226 -0
- data/lib/flare/tools/cli/index.rb +54 -0
- data/lib/flare/tools/cli/list.rb +93 -0
- data/lib/flare/tools/cli/master.rb +143 -0
- data/lib/flare/tools/cli/part.rb +100 -0
- data/lib/flare/tools/cli/ping.rb +81 -0
- data/lib/flare/tools/cli/reconstruct.rb +164 -0
- data/lib/flare/tools/cli/remove.rb +119 -0
- data/lib/flare/tools/cli/restore.rb +180 -0
- data/lib/flare/tools/cli/slave.rb +125 -0
- data/lib/flare/tools/cli/stats.rb +229 -122
- data/lib/flare/tools/cli/sub_command.rb +73 -0
- data/lib/flare/tools/cli/summary.rb +97 -0
- data/lib/flare/tools/cli/threads.rb +78 -0
- data/lib/flare/tools/cli/verify.rb +202 -0
- data/lib/flare/tools/client.rb +267 -0
- data/lib/flare/tools/cluster.rb +319 -0
- data/lib/flare/tools/common.rb +196 -0
- data/lib/flare/tools/index_server.rb +51 -0
- data/lib/flare/tools/node.rb +162 -0
- data/lib/flare/tools/stats.rb +75 -0
- data/lib/flare/tools/zk_util.rb +28 -0
- data/lib/flare/util.rb +34 -0
- data/lib/flare/util/bwlimit.rb +132 -0
- data/lib/flare/util/command_line.rb +79 -0
- data/lib/flare/util/conf.rb +71 -0
- data/lib/flare/util/constant.rb +25 -0
- data/lib/flare/util/conversion.rb +26 -0
- data/lib/flare/util/default_logger.rb +52 -0
- data/lib/flare/util/exception.rb +19 -0
- data/lib/flare/util/filesystem.rb +30 -0
- data/lib/flare/util/flared_conf.rb +33 -0
- data/lib/flare/util/flarei_conf.rb +32 -0
- data/lib/flare/util/hash_function.rb +32 -0
- data/lib/flare/util/interruption.rb +70 -0
- data/lib/flare/util/key_resolver.rb +67 -0
- data/lib/flare/util/log4r_logger.rb +79 -0
- data/lib/flare/util/logger.rb +40 -0
- data/lib/flare/util/logging.rb +84 -0
- data/lib/flare/util/result.rb +53 -0
- data/test/test/experimental/cache_test.rb +113 -0
- data/test/test/experimental/key_distribution_test.rb +38 -0
- data/test/test/experimental/keychecker_test.rb +60 -0
- data/test/test/experimental/list_test.rb +108 -0
- data/test/test/extra/replication_test.rb +184 -0
- data/test/test/integration/cli_test.rb +348 -0
- data/test/test/integration/dump_expired_test.rb +103 -0
- data/test/test/integration/dump_test.rb +128 -0
- data/test/test/integration/index_server_test.rb +35 -0
- data/test/test/integration/node_test.rb +78 -0
- data/test/test/integration/partition_test.rb +235 -0
- data/test/test/integration/proxy_test.rb +54 -0
- data/test/test/integration/stats_test.rb +79 -0
- data/test/test/system/flare_admin_test.rb +191 -0
- data/test/test/unit/bwlimit_test.rb +52 -0
- data/test/test/unit/cluster_test.rb +96 -0
- data/test/test/unit/daemon_test.rb +30 -0
- data/test/test/unit/logger_test.rb +46 -0
- data/test/test/unit/tools_test.rb +25 -0
- data/test/test/unit/util_test.rb +70 -0
- metadata +239 -84
- data/README.rdoc +0 -83
- data/bin/flare-partition-setting +0 -12
- data/lib/flare/tools/cli/partition_setting.rb +0 -86
- data/lib/flare/tools/core.rb +0 -189
- data/lib/flare/tools/logger.rb +0 -31
- data/test/test_flare-tools.rb +0 -11
- data/test/test_helper.rb +0 -3
@@ -0,0 +1,196 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'resolv'
|
7
|
+
require 'flare/tools/cluster'
|
8
|
+
require 'flare/tools/stats'
|
9
|
+
require 'flare/util/constant'
|
10
|
+
require 'flare/util/logging'
|
11
|
+
|
12
|
+
#
|
13
|
+
module Flare
|
14
|
+
module Tools
|
15
|
+
module Common
|
16
|
+
include Flare::Util::Logging
|
17
|
+
|
18
|
+
def fetch_cluster s
|
19
|
+
Flare::Tools::Cluster.new(s.host, s.port, s.stats_nodes)
|
20
|
+
end
|
21
|
+
|
22
|
+
def user_confirmed opt = { true => /^Y$/, false => /^N$/ }, &block
|
23
|
+
ret = nil
|
24
|
+
while ret.nil?
|
25
|
+
line = gets.chomp.upcase
|
26
|
+
opt.each do |key,pattern|
|
27
|
+
if patterns =~ line
|
28
|
+
ret = key
|
29
|
+
break
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
if block.nil?
|
34
|
+
ret
|
35
|
+
else
|
36
|
+
block.call(ret)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def nodekey_of *args
|
41
|
+
if args.size == 1
|
42
|
+
args = if args[0].kind_of?(Array)
|
43
|
+
args[0]
|
44
|
+
elsif args[0].kind_of?(String)
|
45
|
+
args[0].split(':')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
if args.size >= 2
|
49
|
+
hostname, port = args
|
50
|
+
if hostname.kind_of?(String) && port.kind_of?(String)
|
51
|
+
if port.empty?
|
52
|
+
port = Flare::Util::Constant::DefaultNodePort
|
53
|
+
return "#{hostname}:#{port}"
|
54
|
+
elsif /^\d+$/ =~ port
|
55
|
+
return "#{hostname}:#{port}"
|
56
|
+
end
|
57
|
+
elsif hostname.kind_of?(String) && port.kind_of?(Integer)
|
58
|
+
return "#{hostname}:#{port}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def address_of_hostname(hostname)
|
65
|
+
Resolv.getaddress(hostname)
|
66
|
+
rescue Resolv::ResolvError
|
67
|
+
hostname
|
68
|
+
end
|
69
|
+
|
70
|
+
def hostname_of_address(ipaddr)
|
71
|
+
Resolv.getname(ipaddr)
|
72
|
+
rescue Resolv::ResolvError
|
73
|
+
ipaddr
|
74
|
+
end
|
75
|
+
|
76
|
+
NodeListHeader = [ ['%-32s', 'node'],
|
77
|
+
['%9s', 'partition'],
|
78
|
+
['%6s', 'role'],
|
79
|
+
['%6s', 'state'],
|
80
|
+
['%7s', 'balance'] ]
|
81
|
+
NodeListFormat = (NodeListHeader.map {|x| x[0]}.join(' '))
|
82
|
+
|
83
|
+
def string_of_nodelist(nodes, opt = {})
|
84
|
+
format = NodeListFormat+"\n"
|
85
|
+
ret = format % NodeListHeader.map{|x| x[1]}.flatten
|
86
|
+
nodes.each do |nodekey, node|
|
87
|
+
if opt.empty? || opt.include?(nodekey)
|
88
|
+
partition = if node['partition'] == "-1"
|
89
|
+
"-"
|
90
|
+
else
|
91
|
+
node['partition']
|
92
|
+
end
|
93
|
+
ret += format % [
|
94
|
+
nodekey,
|
95
|
+
partition,
|
96
|
+
node['role'],
|
97
|
+
node['state'],
|
98
|
+
node['balance'],
|
99
|
+
]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
ret
|
103
|
+
end
|
104
|
+
|
105
|
+
# s:IndexServer, nodekey:"hostname:port", timeout(second):Integer -> state:String
|
106
|
+
def wait_for_slave_construction(index_server, nodekey, timeout, silent = false)
|
107
|
+
cluster = Flare::Tools::Cluster.new(index_server.host, index_server.port, index_server.stats_nodes)
|
108
|
+
slave = cluster.node_stat(nodekey)
|
109
|
+
partition = slave['partition'].to_i
|
110
|
+
m_hostname, m_port = cluster.master_in_partition(partition).split(':')
|
111
|
+
s_hostname, s_port = nodekey.split(':')
|
112
|
+
m = Flare::Tools::Stats.open(m_hostname, m_port.to_i, timeout)
|
113
|
+
s = Flare::Tools::Stats.open(s_hostname, s_port.to_i, timeout)
|
114
|
+
start = Time.now
|
115
|
+
while true
|
116
|
+
cluster = Flare::Tools::Cluster.new(index_server.host, index_server.port, index_server.stats_nodes)
|
117
|
+
slave = cluster.node_stat(nodekey)
|
118
|
+
stats_master = m.stats
|
119
|
+
stats_slave = s.stats
|
120
|
+
ts_diff = Time.now-start
|
121
|
+
state_slave = slave['state'];
|
122
|
+
role_slave = slave['role'];
|
123
|
+
item_m = stats_master['curr_items'].to_i;
|
124
|
+
item_s = stats_slave['curr_items'].to_i;
|
125
|
+
eta = if ts_diff > 0 && item_s > 0
|
126
|
+
((item_m - item_s) / (item_s / ts_diff)).to_i;
|
127
|
+
else
|
128
|
+
"n/a";
|
129
|
+
end
|
130
|
+
unless silent
|
131
|
+
STDERR.puts "%d/%d (role = %s, state = %s) [ETA: %s sec (elapsed = %d sec)]" % [item_s, item_m, role_slave, state_slave, eta, ts_diff]
|
132
|
+
end
|
133
|
+
break if role_slave == "slave" && state_slave == "active"
|
134
|
+
sleep 1
|
135
|
+
end
|
136
|
+
info "state is active -> stop waiting" unless silent
|
137
|
+
m.close
|
138
|
+
s.close
|
139
|
+
state_slave
|
140
|
+
end
|
141
|
+
|
142
|
+
# s:IndexServer, nodekey:"hostname:port", timeout(second):Integer -> state:String
|
143
|
+
def wait_for_master_construction(index_server, nodekey, timeout, silent = false)
|
144
|
+
cluster = Flare::Tools::Cluster.new(index_server.host, index_server.port, index_server.stats_nodes)
|
145
|
+
master = cluster.node_stat(nodekey)
|
146
|
+
partition = master['partition'].to_i
|
147
|
+
m_hostname, m_port = cluster.master_in_partition(partition).split(':')
|
148
|
+
m = Flare::Tools::Stats.open(m_hostname, m_port.to_i, timeout)
|
149
|
+
start = Time.now
|
150
|
+
while true
|
151
|
+
cluster = Flare::Tools::Cluster.new(index_server.host, index_server.port, index_server.stats_nodes)
|
152
|
+
master = cluster.node_stat(nodekey)
|
153
|
+
stats_master = m.stats
|
154
|
+
ts_diff = Time.now-start
|
155
|
+
state_master = master['state'];
|
156
|
+
role_master = master['role'];
|
157
|
+
item_m = stats_master['curr_items'].to_i;
|
158
|
+
eta = "n/a";
|
159
|
+
unless silent
|
160
|
+
STDERR.puts "%d (role = %s, state = %s) [ETA: %s sec (elapsed = %d sec)]" % [item_m, role_master, state_master, eta, ts_diff]
|
161
|
+
end
|
162
|
+
if role_master == "master" && state_master == "active"
|
163
|
+
if partition != 0
|
164
|
+
warn "The master should be ready after the reconstruction but it became active."
|
165
|
+
end
|
166
|
+
break
|
167
|
+
end
|
168
|
+
break if role_master == "master" && state_master == "ready"
|
169
|
+
sleep 1
|
170
|
+
end
|
171
|
+
info "state is ready -> stop waiting" unless silent
|
172
|
+
m.close
|
173
|
+
state_master
|
174
|
+
end
|
175
|
+
|
176
|
+
def wait_for_servers(index_server, timeout = Flare::Util::Constant::DefaultTimeout, silent = false)
|
177
|
+
index_server.stats_nodes.each do |nodekey, v|
|
178
|
+
hostname, port = nodekey.split(':')
|
179
|
+
is_alive = false
|
180
|
+
while is_alive
|
181
|
+
begin
|
182
|
+
Flare::Tools::Node.open(hostname, port.to_i, 2) do |n|
|
183
|
+
n.ping
|
184
|
+
is_alize = true
|
185
|
+
end
|
186
|
+
rescue Errno::ECONNREFUSED
|
187
|
+
rescue SocketError
|
188
|
+
end
|
189
|
+
sleep 1 unless is_alive
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/tools/stats'
|
7
|
+
|
8
|
+
#
|
9
|
+
module Flare
|
10
|
+
module Tools
|
11
|
+
|
12
|
+
# == Description
|
13
|
+
#
|
14
|
+
class IndexServer < Stats
|
15
|
+
|
16
|
+
def set_role(host, port, role, balance, partition)
|
17
|
+
set_role_(host, port, role, balance, partition)
|
18
|
+
end
|
19
|
+
defcmd :set_role_, 'node role %s %d %s %d %d\r\n' do |resp|
|
20
|
+
resp
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_state(host, port, state)
|
24
|
+
set_state_(host, port, state)
|
25
|
+
end
|
26
|
+
defcmd :set_state_, 'node state %s %s %s\r\n' do |resp|
|
27
|
+
resp
|
28
|
+
end
|
29
|
+
|
30
|
+
def node_remove(host, port)
|
31
|
+
node_remove_(host, port)
|
32
|
+
end
|
33
|
+
defcmd :node_remove_, 'node remove %s %s\r\n' do |resp|
|
34
|
+
resp
|
35
|
+
end
|
36
|
+
|
37
|
+
def meta()
|
38
|
+
meta_()
|
39
|
+
end
|
40
|
+
defcmd :meta_, 'meta\r\n' do |resp|
|
41
|
+
result = {}
|
42
|
+
resp.gsub(/META /, '').split("\r\n").each do |x|
|
43
|
+
key, val = x.split(" ", 2)
|
44
|
+
result[key] = val
|
45
|
+
end
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'flare/tools/stats'
|
7
|
+
|
8
|
+
#
|
9
|
+
module Flare
|
10
|
+
module Tools
|
11
|
+
|
12
|
+
# == Description
|
13
|
+
#
|
14
|
+
class Node < Stats
|
15
|
+
|
16
|
+
def set_state(host, port, state)
|
17
|
+
set_state_(host, port, state)
|
18
|
+
end
|
19
|
+
defcmd :set_state_, 'node state %s %s %s\r\n' do |resp| resp end
|
20
|
+
|
21
|
+
def flush_all
|
22
|
+
flush_all_
|
23
|
+
end
|
24
|
+
defcmd :flush_all_, 'flush_all\r\n' do |resp| resp end
|
25
|
+
|
26
|
+
def x_list_push(k, v, flag = 0, expire = 0)
|
27
|
+
x_list_push_(k.chomp, flag, expire, v.size, v)
|
28
|
+
end
|
29
|
+
defcmd :x_list_push_, 'list_push %s %d %d %d\r\n%s\r\n' do |resp| resp end
|
30
|
+
|
31
|
+
def x_list_unshift(k, v, flag = 0, expire = 0)
|
32
|
+
x_list_unshift_(k.chomp, flag, expire, v.size, v)
|
33
|
+
end
|
34
|
+
defcmd :x_list_unshift_, 'list_unshift %s %d %d %d\r\n%s\r\n' do |resp| resp end
|
35
|
+
|
36
|
+
def set(k, v, flag = 0, expire = 0)
|
37
|
+
set_(k.chomp, flag, expire, v.size, v)
|
38
|
+
end
|
39
|
+
defcmd :set_, 'set %s %d %d %d\r\n%s\r\n' do |resp| resp end
|
40
|
+
|
41
|
+
def set_noreply(k, v, flag = 0, expire = 0)
|
42
|
+
set_noreply_(k.chomp, flag, expire, v.size, v)
|
43
|
+
end
|
44
|
+
defcmd_noreply :set_noreply_, 'set %s %d %d %d noreply\r\n%s\r\n'
|
45
|
+
|
46
|
+
def cas(k, v, casunique, flag = 0, expire = 0)
|
47
|
+
r = cas_(k.chomp, flag, expire, v.size, casunique, v)
|
48
|
+
r = true if r == ""
|
49
|
+
r
|
50
|
+
end
|
51
|
+
defcmd :cas_, 'cas %s %d %d %d %d\r\n%s\r\n' do |resp| resp end
|
52
|
+
|
53
|
+
def delete(k)
|
54
|
+
delete_(k.chomp)
|
55
|
+
end
|
56
|
+
defcmd :delete_, 'delete %s\r\n' do |resp| resp end
|
57
|
+
|
58
|
+
def delete_noreply(k)
|
59
|
+
delete_noreply_(k.chomp)
|
60
|
+
end
|
61
|
+
defcmd_noreply :delete_noreply_, 'delete %s noreply\r\n'
|
62
|
+
|
63
|
+
def x_list_pop(k)
|
64
|
+
r = nil
|
65
|
+
x_list_pop_(k.chomp) do |data, key, flag, len, version, expire|
|
66
|
+
r = data
|
67
|
+
end
|
68
|
+
r
|
69
|
+
end
|
70
|
+
defcmd_value :x_list_pop_, 'list_pop %s\r\n'
|
71
|
+
|
72
|
+
def x_list_shift(k)
|
73
|
+
r = nil
|
74
|
+
x_list_shift_(k.chomp) do |data, key, flag, len, version, expire|
|
75
|
+
r = data
|
76
|
+
end
|
77
|
+
r
|
78
|
+
end
|
79
|
+
defcmd_value :x_list_shift_, 'list_shift %s\r\n'
|
80
|
+
|
81
|
+
def x_list_get(k, b, e, &block)
|
82
|
+
x_list_get_(k.chomp, b, e, &block)
|
83
|
+
end
|
84
|
+
defcmd_listelement :x_list_get_, 'list_get %s %d %d\r\n' do |data, key, rel, abs, flag, len, version, expire|
|
85
|
+
data
|
86
|
+
end
|
87
|
+
|
88
|
+
def get(*keys, &block)
|
89
|
+
return false if keys.size == 0
|
90
|
+
r = get_(keys.map{|x|x.chomp}.join(' '), &block)
|
91
|
+
if r && keys.size == 1
|
92
|
+
return false if r.size == 0
|
93
|
+
return r[0] if r.size == 1
|
94
|
+
end
|
95
|
+
r
|
96
|
+
end
|
97
|
+
defcmd_value :get_, 'get %s\r\n' do |data, key, flag, len, version, expire|
|
98
|
+
data
|
99
|
+
end
|
100
|
+
|
101
|
+
def gets(*keys, &block)
|
102
|
+
return false if keys.size == 0
|
103
|
+
r = gets_(keys.map{|x|x.chomp}.join(' '), &block)
|
104
|
+
if r && keys.size == 1
|
105
|
+
return false if r.size == 0
|
106
|
+
return r[0] if r.size == 1
|
107
|
+
end
|
108
|
+
r
|
109
|
+
end
|
110
|
+
defcmd_value :gets_, 'gets %s\r\n' do |data, key, flag, len, version, expire|
|
111
|
+
[data, version]
|
112
|
+
end
|
113
|
+
|
114
|
+
def dump(wait = 0, part = 0, partsize = 1, bwlimit = 0, &block)
|
115
|
+
dump_(wait, part, partsize, bwlimit.to_i, &block)
|
116
|
+
end
|
117
|
+
defcmd_value :dump_, 'dump %d %d %d %d\r\n' do |data, key, flag, len, version, expire|
|
118
|
+
false
|
119
|
+
end
|
120
|
+
|
121
|
+
def dumpkey(part = nil, partsize = nil, &block)
|
122
|
+
return dumpkey_0_(&block) if part.nil?
|
123
|
+
return dumpkey_1_(part, &block) if partsize.nil?
|
124
|
+
return dumpkey_2_(part, partsize, &block)
|
125
|
+
end
|
126
|
+
defcmd_key :dumpkey_0_, 'dump_key\r\n' do |key|
|
127
|
+
false
|
128
|
+
end
|
129
|
+
defcmd_key :dumpkey_1_, 'dump_key %d\r\n' do |key|
|
130
|
+
false
|
131
|
+
end
|
132
|
+
defcmd_key :dumpkey_2_, 'dump_key %d %d\r\n' do |key|
|
133
|
+
false
|
134
|
+
end
|
135
|
+
|
136
|
+
def incr_noreply(k, v)
|
137
|
+
incr_noreply_(k.chomp, v.to_s)
|
138
|
+
end
|
139
|
+
defcmd_noreply :incr_noreply_, 'incr %s %s noreply\r\n'
|
140
|
+
|
141
|
+
def incr(k, v)
|
142
|
+
incr_(k.chomp, v.to_s)
|
143
|
+
end
|
144
|
+
defcmd_oneline :incr_, 'incr %s %s\r\n' do |resp|
|
145
|
+
resp.chomp
|
146
|
+
end
|
147
|
+
|
148
|
+
def decr_noreply(k, v)
|
149
|
+
decr_noreply_(k.chomp, v.to_s)
|
150
|
+
end
|
151
|
+
defcmd_noreply :decr_noreply_, 'decr %s %s noreply\r\n'
|
152
|
+
|
153
|
+
def decr(k, v)
|
154
|
+
decr_(k.chomp, v.to_s)
|
155
|
+
end
|
156
|
+
defcmd_oneline :decr_, 'decr %s %s\r\n' do |resp|
|
157
|
+
resp.chomp
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# -*- coding: utf-8; -*-
|
2
|
+
# Authors:: Kiyoshi Ikehara <kiyoshi.ikehara@gree.net>
|
3
|
+
# Copyright:: Copyright (C) GREE, Inc. 2011.
|
4
|
+
# License:: MIT-style
|
5
|
+
|
6
|
+
require 'timeout'
|
7
|
+
require 'flare/tools/client'
|
8
|
+
|
9
|
+
#
|
10
|
+
module Flare
|
11
|
+
module Tools
|
12
|
+
|
13
|
+
# == Description
|
14
|
+
#
|
15
|
+
class Stats < Client
|
16
|
+
|
17
|
+
defcmd :stats_nodes, 'stats nodes\r\n' do |resp|
|
18
|
+
result = {}
|
19
|
+
resp.gsub(/STAT /, '').split("\r\n").each do |x|
|
20
|
+
ip, port, stat = x.split(":", 3)
|
21
|
+
key, val = stat.split(" ")
|
22
|
+
result["#{ip}:#{port}"] = {} if result["#{ip}:#{port}"].nil?
|
23
|
+
result["#{ip}:#{port}"]['port'] = port
|
24
|
+
result["#{ip}:#{port}"][key] = val
|
25
|
+
end
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
defcmd :stats, 'stats\r\n' do |resp|
|
30
|
+
result = {}
|
31
|
+
resp.gsub(/STAT /, '').split("\r\n").each do |x|
|
32
|
+
key, val = x.split(" ", 2)
|
33
|
+
result[key] = val
|
34
|
+
end
|
35
|
+
result
|
36
|
+
end
|
37
|
+
|
38
|
+
def stats_threads_by_peer
|
39
|
+
result = {}
|
40
|
+
stats_threads.each do |thread_id, stat|
|
41
|
+
k = stat['peer']
|
42
|
+
result[k] = {} if result[k].nil?
|
43
|
+
result[k]['thread_id'] = thread_id
|
44
|
+
result[k].merge!(stat)
|
45
|
+
end
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
def stats_threads
|
50
|
+
return {} unless required_version?([1, 0, 10])
|
51
|
+
stats_threads_
|
52
|
+
end
|
53
|
+
|
54
|
+
defcmd :stats_threads_, 'stats threads\r\n' do |resp|
|
55
|
+
threads = {}
|
56
|
+
resp.gsub(/STAT /, '').split("\r\n").each do |x|
|
57
|
+
thread_id, stat = x.split(":", 2)
|
58
|
+
key, val = stat.split(" ")
|
59
|
+
threads[thread_id] = {} unless threads.has_key?(thread_id)
|
60
|
+
threads[thread_id][key] = val
|
61
|
+
end
|
62
|
+
threads
|
63
|
+
end
|
64
|
+
|
65
|
+
defcmd :ping, 'ping\r\n' do |resp|
|
66
|
+
true if resp
|
67
|
+
end
|
68
|
+
|
69
|
+
defcmd :quit, 'quit\r\n' do |resp|
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|