roma 0.8.2 → 0.8.10
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/CHANG +326 -0
- data/CHANGELOG +132 -0
- data/{README.rdoc → FETCH_HEAD} +0 -0
- data/{LICENSE.rdoc → LICENSE} +0 -1
- data/README +17 -0
- data/Rakefile +33 -18
- data/ruby/server/bin/chg_redundancy +10 -0
- data/ruby/server/bin/key_access +7 -0
- data/ruby/server/bin/key_list +7 -0
- data/ruby/server/bin/mkconfig +19 -0
- data/{bin → ruby/server/bin}/mkrecent +0 -1
- data/{bin → ruby/server/bin}/mkroute +0 -1
- data/ruby/server/bin/multi_commander +19 -0
- data/ruby/server/bin/recoverlost +10 -0
- data/ruby/server/bin/recoverlost_alist +10 -0
- data/ruby/server/bin/recoverlost_alist_all +10 -0
- data/ruby/server/bin/recoverlost_alist_keys +10 -0
- data/{bin/recoverlost → ruby/server/bin/roma_watcher} +1 -2
- data/ruby/server/bin/romad +36 -0
- data/{bin → ruby/server/bin}/sample_watcher +0 -1
- data/{bin → ruby/server/bin}/sample_watcher2 +0 -1
- data/{bin/simple_bench → ruby/server/bin/sample_watcher3} +1 -2
- data/ruby/server/bin/simple_bench +26 -0
- data/{bin → ruby/server/bin}/ssroute +0 -1
- data/ruby/server/bin/test-scenario +11 -0
- data/{bin → ruby/server/bin}/tribunus +0 -1
- data/{lib → ruby/server/lib}/roma/async_process.rb +67 -15
- data/{lib → ruby/server/lib}/roma/command/bg_command_receiver.rb +1 -1
- data/ruby/server/lib/roma/command/command_definition.rb +422 -0
- data/ruby/server/lib/roma/command/mh_command_receiver.rb +127 -0
- data/ruby/server/lib/roma/command/receiver.rb +64 -0
- data/{lib → ruby/server/lib}/roma/command/rt_command_receiver.rb +6 -1
- data/ruby/server/lib/roma/command/sys_command_receiver.rb +609 -0
- data/{lib → ruby/server/lib}/roma/command/util_command_receiver.rb +15 -5
- data/{lib → ruby/server/lib}/roma/command/vn_command_receiver.rb +12 -4
- data/{lib → ruby/server/lib}/roma/command_plugin.rb +0 -0
- data/ruby/server/lib/roma/config.rb +84 -0
- data/{lib → ruby/server/lib}/roma/event/con_pool.rb +12 -1
- data/ruby/server/lib/roma/event/handler.rb +256 -0
- data/ruby/server/lib/roma/live_patch-20120302-001.rb +107 -0
- data/ruby/server/lib/roma/logging/rlogger.rb +163 -0
- data/ruby/server/lib/roma/messaging/con_pool.rb +92 -0
- data/{lib → ruby/server/lib}/roma/plugin/plugin_alist.rb +118 -240
- data/ruby/server/lib/roma/plugin/plugin_debug.rb +31 -0
- data/ruby/server/lib/roma/plugin/plugin_map.rb +177 -0
- data/ruby/server/lib/roma/plugin/plugin_mapcount.rb +185 -0
- data/{lib/roma/command/st_command_receiver.rb → ruby/server/lib/roma/plugin/plugin_storage.rb} +170 -146
- data/ruby/server/lib/roma/plugin/plugin_stub.rb +283 -0
- data/{lib → ruby/server/lib}/roma/plugin/plugin_test.rb +0 -0
- data/{lib → ruby/server/lib}/roma/romad.rb +221 -94
- data/{lib → ruby/server/lib}/roma/routing/cb_rttable.rb +4 -6
- data/{lib → ruby/server/lib}/roma/routing/merkle_tree.rb +0 -0
- data/ruby/server/lib/roma/routing/routing_data.rb +307 -0
- data/{lib → ruby/server/lib}/roma/routing/rttable.rb +4 -0
- data/{lib → ruby/server/lib}/roma/stats.rb +19 -3
- data/{lib → ruby/server/lib}/roma/storage/basic_storage.rb +25 -26
- data/{lib → ruby/server/lib}/roma/storage/dbm_storage.rb +1 -23
- data/{lib → ruby/server/lib}/roma/storage/dummy_storage.rb +0 -0
- data/{lib → ruby/server/lib}/roma/storage/rh_storage.rb +0 -0
- data/{lib → ruby/server/lib}/roma/storage/sqlite3_storage.rb +0 -0
- data/{lib → ruby/server/lib}/roma/storage/tc_storage.rb +62 -2
- data/ruby/server/lib/roma/tools/chg_redundancy.rb +36 -0
- data/ruby/server/lib/roma/tools/key_access.rb +105 -0
- data/ruby/server/lib/roma/tools/key_list.rb +94 -0
- data/ruby/server/lib/roma/tools/mkconfig.rb +535 -0
- data/{lib → ruby/server/lib}/roma/tools/mkrecent.rb +0 -0
- data/{lib → ruby/server/lib}/roma/tools/mkroute.rb +0 -0
- data/ruby/server/lib/roma/tools/multi_commander.rb +45 -0
- data/{lib → ruby/server/lib}/roma/tools/recoverlost.rb +0 -0
- data/{lib → ruby/server/lib}/roma/tools/recoverlost_alist.rb +0 -0
- data/ruby/server/lib/roma/tools/recoverlost_alist_all.rb +8 -0
- data/ruby/server/lib/roma/tools/recoverlost_alist_keys.rb +16 -0
- data/ruby/server/lib/roma/tools/recoverlost_lib.rb +349 -0
- data/ruby/server/lib/roma/tools/roma_watcher.rb +150 -0
- data/ruby/server/lib/roma/tools/roma_watcher_config.yml.example +20 -0
- data/{lib → ruby/server/lib}/roma/tools/sample_watcher.rb +3 -1
- data/{lib → ruby/server/lib}/roma/tools/sample_watcher2.rb +3 -1
- data/ruby/server/lib/roma/tools/sample_watcher3.rb +49 -0
- data/{lib → ruby/server/lib}/roma/tools/simple_bench.rb +2 -0
- data/ruby/server/lib/roma/tools/simple_bench2.rb +78 -0
- data/{lib → ruby/server/lib}/roma/tools/ssroute.rb +0 -0
- data/ruby/server/lib/roma/tools/test-scenario.rb +327 -0
- data/{lib → ruby/server/lib}/roma/tools/tribunus.rb +0 -0
- data/ruby/server/lib/roma/version.rb +4 -0
- data/{lib → ruby/server/lib}/roma/write_behind.rb +1 -0
- data/ruby/server/test/config4mhash.rb +68 -0
- data/ruby/server/test/config4storage_error.rb +69 -0
- data/{lib/roma/config.rb → ruby/server/test/config4test.rb} +6 -3
- data/{test → ruby/server/test}/rcirb.rb +0 -1
- data/{test → ruby/server/test}/roma-test-utils.rb +21 -8
- data/{test → ruby/server/test}/run-test.rb +3 -2
- data/ruby/server/test/storage_error_storage.rb +37 -0
- data/ruby/server/test/t_command_definition.rb +326 -0
- data/{test → ruby/server/test}/t_cpdata.rb +9 -3
- data/{test → ruby/server/test}/t_listplugin.rb +48 -12
- data/ruby/server/test/t_mapcountplugin.rb +231 -0
- data/ruby/server/test/t_mapplugin.rb +131 -0
- data/ruby/server/test/t_mhash.rb +222 -0
- data/ruby/server/test/t_rclient.rb +199 -0
- data/{test → ruby/server/test}/t_routing_data.rb +56 -0
- data/{test → ruby/server/test}/t_storage.rb +107 -111
- data/ruby/server/test/t_storage_error.rb +61 -0
- data/ruby/server/test/t_writebehind.rb +374 -0
- metadata +150 -82
- data/bin/recoverlost_alist +0 -8
- data/bin/romad +0 -7
- data/lib/roma/command/mh_command_receiver.rb +0 -117
- data/lib/roma/command/receiver.rb +0 -287
- data/lib/roma/event/handler.rb +0 -159
- data/lib/roma/plugin/plugin_debug.rb +0 -19
- data/lib/roma/tools/recoverlost_lib.rb +0 -217
- data/lib/roma/version.rb +0 -4
- data/test/t_rclient.rb +0 -318
- data/test/t_writebehind.rb +0 -200
@@ -0,0 +1,422 @@
|
|
1
|
+
module Roma
|
2
|
+
module Command
|
3
|
+
module Definition
|
4
|
+
|
5
|
+
class ClientErrorException < Exception; end
|
6
|
+
class ServerErrorException < Exception; end
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
# include ClassMethods module into an eigen-class of a +base+
|
10
|
+
base.extend ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
def def_command_with_relay(cmd, &block)
|
16
|
+
# check a duplicated command definition in a same scope
|
17
|
+
if public_method_defined? "ev_#{cmd}".to_sym
|
18
|
+
raise "ev_#{cmd} already defined."
|
19
|
+
end
|
20
|
+
|
21
|
+
# define a command receiver
|
22
|
+
define_method "ev_#{cmd}" do |s|
|
23
|
+
begin
|
24
|
+
res = {}
|
25
|
+
res[@stats.ap_str] = instance_exec(s, &block)
|
26
|
+
# command relay
|
27
|
+
res.merge! broadcast_cmd("r#{cmd} #{s[1..-1].join(' ')}\r\n")
|
28
|
+
send_data("#{res}\r\n")
|
29
|
+
rescue ClientErrorException => e
|
30
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
31
|
+
rescue ServerErrorException => e
|
32
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
33
|
+
rescue LocalJumpError => e
|
34
|
+
@log.warn("#{e} #{$@}")
|
35
|
+
e.exit_value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# define a relaid command receiver
|
40
|
+
define_method "ev_r#{cmd}" do |s|
|
41
|
+
begin
|
42
|
+
send_data("#{instance_exec(s, &block)}\r\n")
|
43
|
+
rescue ClientErrorException => e
|
44
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
45
|
+
rescue ServerErrorException => e
|
46
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
47
|
+
rescue LocalJumpError => e
|
48
|
+
@log.warn("#{e} #{$@}")
|
49
|
+
e.exit_value
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end # def_command_with_relay
|
53
|
+
|
54
|
+
CommandParams = Struct.new(:key, :hash_name, :digest, :vn, :nodes, :value)
|
55
|
+
StoredData = Struct.new(:vn, :last, :clk, :flg, :expt, :value)
|
56
|
+
CommandContext = Struct.new(:argv, :params, :stored)
|
57
|
+
|
58
|
+
def def_read_command_with_key(cmd, forward = :one_line, &block)
|
59
|
+
define_method "ev_#{cmd}" do |s|
|
60
|
+
return send_data("CLIENT_ERROR dose not find key\r\n") if s.length < 2
|
61
|
+
begin
|
62
|
+
params = CommandParams.new
|
63
|
+
params.key, params.hash_name = s[1].split("\e")
|
64
|
+
params.hash_name ||= @defhash
|
65
|
+
params.digest = Digest::SHA1.hexdigest(params.key).hex % @rttable.hbits
|
66
|
+
params.vn = @rttable.get_vnode_id(params.digest)
|
67
|
+
params.nodes = @rttable.search_nodes_for_write(params.vn)
|
68
|
+
if params.nodes[0] != @nid
|
69
|
+
if forward == :one_line
|
70
|
+
return forward_and_one_line_receive(params.nodes[0], s)
|
71
|
+
elsif forward == :multi_line
|
72
|
+
return forward_and_multi_line_receive(params.nodes[0], s)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
stored = StoredData.new
|
76
|
+
unless @storages[params.hash_name]
|
77
|
+
return send_data("SERVER_ERROR #{params.hash_name} dose not exists.\r\n")
|
78
|
+
end
|
79
|
+
|
80
|
+
stored.vn, stored.last, stored.clk, stored.expt, stored.value =
|
81
|
+
@storages[params.hash_name].get_raw(params.vn, params.key, params.digest)
|
82
|
+
stored = nil if stored.vn == nil || Time.now.to_i > stored.expt
|
83
|
+
ctx = CommandContext.new(s, params, stored)
|
84
|
+
instance_exec(ctx, &block)
|
85
|
+
@stats.read_count += 1
|
86
|
+
rescue ClientErrorException => e
|
87
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
88
|
+
rescue ServerErrorException => e
|
89
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
90
|
+
rescue LocalJumpError => e
|
91
|
+
@log.warn("#{e} #{$@}")
|
92
|
+
e.exit_value
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end # def_read_command_with_key
|
96
|
+
|
97
|
+
def def_write_command_with_key(cmd, forward = :one_line, &block)
|
98
|
+
define_method "ev_#{cmd}" do |s|
|
99
|
+
return send_data("CLIENT_ERROR dose not find key\r\n") if s.length < 2
|
100
|
+
begin
|
101
|
+
params = CommandParams.new
|
102
|
+
params.key, params.hash_name = s[1].split("\e")
|
103
|
+
params.hash_name ||= @defhash
|
104
|
+
params.digest = Digest::SHA1.hexdigest(params.key).hex % @rttable.hbits
|
105
|
+
params.vn = @rttable.get_vnode_id(params.digest)
|
106
|
+
params.nodes = @rttable.search_nodes_for_write(params.vn)
|
107
|
+
if params.nodes[0] != @nid
|
108
|
+
if forward == :one_line
|
109
|
+
return forward_and_one_line_receive(params.nodes[0], s)
|
110
|
+
elsif forward == :multi_line
|
111
|
+
return forward_and_multi_line_receive(params.nodes[0], s)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
stored = StoredData.new
|
115
|
+
unless @storages[params.hash_name]
|
116
|
+
return send_data("SERVER_ERROR #{params.hash_name} dose not exists.\r\n")
|
117
|
+
end
|
118
|
+
|
119
|
+
stored.vn, stored.last, stored.clk, stored.expt, stored.value =
|
120
|
+
@storages[params.hash_name].get_raw(params.vn, params.key, params.digest)
|
121
|
+
stored = nil if stored.vn == nil || Time.now.to_i > stored.expt
|
122
|
+
ctx = CommandContext.new(s, params, stored)
|
123
|
+
|
124
|
+
ret = instance_exec(ctx, &block)
|
125
|
+
if ret.instance_of? Array
|
126
|
+
flg, expt, value, count, msg = ret
|
127
|
+
ret = @storages[ctx.params.hash_name].set(ctx.params.vn,
|
128
|
+
ctx.params.key,
|
129
|
+
ctx.params.digest,
|
130
|
+
expt,
|
131
|
+
value)
|
132
|
+
if count == :write
|
133
|
+
@stats.write_count += 1
|
134
|
+
elsif count == :delete
|
135
|
+
@stats.delete_count += 1
|
136
|
+
end
|
137
|
+
|
138
|
+
if ret
|
139
|
+
if @stats.wb_command_map.key?(cmd.to_sym)
|
140
|
+
Roma::WriteBehindProcess::push(ctx.params.hash_name, @stats.wb_command_map[cmd.to_sym], ctx.params.key, ret[4])
|
141
|
+
end
|
142
|
+
redundant(ctx.params.nodes[1..-1], ctx.params.hash_name,
|
143
|
+
ctx.params.key, ctx.params.digest, ret[2],
|
144
|
+
expt, ret[4])
|
145
|
+
send_data("#{msg}\r\n")
|
146
|
+
else
|
147
|
+
send_data("NOT_#{msg}\r\n")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
rescue ClientErrorException => e
|
151
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
152
|
+
rescue ServerErrorException => e
|
153
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
154
|
+
rescue LocalJumpError => e
|
155
|
+
@log.warn("#{e} #{$@}")
|
156
|
+
e.exit_value
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end # def_write_command_with_key
|
160
|
+
|
161
|
+
def def_command_with_key(cmd, forward = :one_line, &block)
|
162
|
+
define_method "ev_#{cmd}" do |s|
|
163
|
+
return send_data("CLIENT_ERROR dose not find key\r\n") if s.length < 2
|
164
|
+
begin
|
165
|
+
params = CommandParams.new
|
166
|
+
params.key, params.hash_name = s[1].split("\e")
|
167
|
+
params.hash_name ||= @defhash
|
168
|
+
params.digest = Digest::SHA1.hexdigest(params.key).hex % @rttable.hbits
|
169
|
+
params.vn = @rttable.get_vnode_id(params.digest)
|
170
|
+
params.nodes = @rttable.search_nodes_for_write(params.vn)
|
171
|
+
if params.nodes[0] != @nid
|
172
|
+
if forward == :one_line
|
173
|
+
return forward_and_one_line_receive(params.nodes[0], s)
|
174
|
+
elsif forward == :multi_line
|
175
|
+
return forward_and_multi_line_receive(params.nodes[0], s)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
stored = StoredData.new
|
179
|
+
unless @storages[params.hash_name]
|
180
|
+
return send_data("SERVER_ERROR #{params.hash_name} dose not exists.\r\n")
|
181
|
+
end
|
182
|
+
|
183
|
+
stored.vn, stored.last, stored.clk, stored.expt, stored.value =
|
184
|
+
@storages[params.hash_name].get_raw(params.vn, params.key, params.digest)
|
185
|
+
stored = nil if stored.vn == nil || Time.now.to_i > stored.expt
|
186
|
+
ctx = CommandContext.new(s, params, stored)
|
187
|
+
instance_exec(ctx, &block)
|
188
|
+
rescue ClientErrorException => e
|
189
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
190
|
+
rescue ServerErrorException => e
|
191
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
192
|
+
rescue LocalJumpError => e
|
193
|
+
@log.warn("#{e} #{$@}")
|
194
|
+
e.exit_value
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end # def_command_with_key
|
198
|
+
|
199
|
+
def def_write_command_with_key_value(cmd, idx_of_val_len, forward = :one_line, &block)
|
200
|
+
define_method "ev_#{cmd}" do |s|
|
201
|
+
return send_data("CLIENT_ERROR dose not find key\r\n") if s.length < 2
|
202
|
+
begin
|
203
|
+
params = CommandParams.new
|
204
|
+
params.key, params.hash_name = s[1].split("\e")
|
205
|
+
params.hash_name ||= @defhash
|
206
|
+
params.digest = Digest::SHA1.hexdigest(params.key).hex % @rttable.hbits
|
207
|
+
params.vn = @rttable.get_vnode_id(params.digest)
|
208
|
+
params.nodes = @rttable.search_nodes_for_write(params.vn)
|
209
|
+
params.value = read_bytes(s[idx_of_val_len].to_i)
|
210
|
+
read_bytes(2)
|
211
|
+
if params.nodes[0] != @nid
|
212
|
+
if forward == :one_line
|
213
|
+
return forward_and_one_line_receive(params.nodes[0], s, params.value)
|
214
|
+
elsif forward == :multi_line
|
215
|
+
return forward_and_multi_line_receive(params.nodes[0], s, params.value)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
stored = StoredData.new
|
219
|
+
unless @storages[params.hash_name]
|
220
|
+
return send_data("SERVER_ERROR #{params.hash_name} dose not exists.\r\n")
|
221
|
+
end
|
222
|
+
|
223
|
+
stored.vn, stored.last, stored.clk, stored.expt, stored.value =
|
224
|
+
@storages[params.hash_name].get_raw(params.vn, params.key, params.digest)
|
225
|
+
stored = nil if stored.vn == nil || Time.now.to_i > stored.expt
|
226
|
+
ctx = CommandContext.new(s, params, stored)
|
227
|
+
|
228
|
+
ret = instance_exec(ctx, &block)
|
229
|
+
if ret.instance_of? Array
|
230
|
+
flg, expt, value, count, msg = ret
|
231
|
+
ret = @storages[ctx.params.hash_name].set(ctx.params.vn,
|
232
|
+
ctx.params.key,
|
233
|
+
ctx.params.digest,
|
234
|
+
expt,
|
235
|
+
value)
|
236
|
+
if count == :write
|
237
|
+
@stats.write_count += 1
|
238
|
+
elsif count == :delete
|
239
|
+
@stats.delete_count += 1
|
240
|
+
end
|
241
|
+
|
242
|
+
if ret
|
243
|
+
if @stats.wb_command_map.key?(cmd.to_sym)
|
244
|
+
Roma::WriteBehindProcess::push(ctx.params.hash_name, @stats.wb_command_map[cmd.to_sym], ctx.params.key, ctx.params.value)
|
245
|
+
end
|
246
|
+
redundant(ctx.params.nodes[1..-1], ctx.params.hash_name,
|
247
|
+
ctx.params.key, ctx.params.digest, ret[2],
|
248
|
+
expt, ret[4])
|
249
|
+
send_data("#{msg}\r\n")
|
250
|
+
else
|
251
|
+
send_data("NOT_#{msg}\r\n")
|
252
|
+
end
|
253
|
+
end
|
254
|
+
rescue ClientErrorException => e
|
255
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
256
|
+
rescue ServerErrorException => e
|
257
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
258
|
+
rescue LocalJumpError => e
|
259
|
+
@log.warn("#{e} #{$@}")
|
260
|
+
e.exit_value
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end # def_write_command_with_key_value
|
264
|
+
|
265
|
+
def def_read_command_with_key_value(cmd, idx_of_val_len, forward = :one_line, &block)
|
266
|
+
define_method "ev_#{cmd}" do |s|
|
267
|
+
return send_data("CLIENT_ERROR dose not find key\r\n") if s.length < 2
|
268
|
+
begin
|
269
|
+
params = CommandParams.new
|
270
|
+
params.key, params.hash_name = s[1].split("\e")
|
271
|
+
params.hash_name ||= @defhash
|
272
|
+
params.digest = Digest::SHA1.hexdigest(params.key).hex % @rttable.hbits
|
273
|
+
params.vn = @rttable.get_vnode_id(params.digest)
|
274
|
+
params.nodes = @rttable.search_nodes_for_write(params.vn)
|
275
|
+
params.value = read_bytes(s[idx_of_val_len].to_i)
|
276
|
+
read_bytes(2)
|
277
|
+
if params.nodes[0] != @nid
|
278
|
+
if forward == :one_line
|
279
|
+
return forward_and_one_line_receive(params.nodes[0], s, params.value)
|
280
|
+
elsif forward == :multi_line
|
281
|
+
return forward_and_multi_line_receive(params.nodes[0], s, params.value)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
stored = StoredData.new
|
285
|
+
unless @storages[params.hash_name]
|
286
|
+
return send_data("SERVER_ERROR #{params.hash_name} dose not exists.\r\n")
|
287
|
+
end
|
288
|
+
|
289
|
+
stored.vn, stored.last, stored.clk, stored.expt, stored.value =
|
290
|
+
@storages[params.hash_name].get_raw(params.vn, params.key, params.digest)
|
291
|
+
stored = nil if stored.vn == nil || Time.now.to_i > stored.expt
|
292
|
+
ctx = CommandContext.new(s, params, stored)
|
293
|
+
|
294
|
+
instance_exec(ctx, &block)
|
295
|
+
@stats.read_count += 1
|
296
|
+
rescue ClientErrorException => e
|
297
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
298
|
+
rescue ServerErrorException => e
|
299
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
300
|
+
rescue LocalJumpError => e
|
301
|
+
@log.warn("#{e} #{$@}")
|
302
|
+
e.exit_value
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end # def_read_command_with_key_value
|
306
|
+
|
307
|
+
def def_command_with_key_value(cmd, idx_of_val_len, forward = :one_line, &block)
|
308
|
+
define_method "ev_#{cmd}" do |s|
|
309
|
+
return send_data("CLIENT_ERROR dose not find key\r\n") if s.length < 2
|
310
|
+
begin
|
311
|
+
params = CommandParams.new
|
312
|
+
params.key, params.hash_name = s[1].split("\e")
|
313
|
+
params.hash_name ||= @defhash
|
314
|
+
params.digest = Digest::SHA1.hexdigest(params.key).hex % @rttable.hbits
|
315
|
+
params.vn = @rttable.get_vnode_id(params.digest)
|
316
|
+
params.nodes = @rttable.search_nodes_for_write(params.vn)
|
317
|
+
params.value = read_bytes(s[idx_of_val_len].to_i)
|
318
|
+
read_bytes(2)
|
319
|
+
if params.nodes[0] != @nid
|
320
|
+
if forward == :one_line
|
321
|
+
return forward_and_one_line_receive(params.nodes[0], s, params.value)
|
322
|
+
elsif forward == :multi_line
|
323
|
+
return forward_and_multi_line_receive(params.nodes[0], s, params.value)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
stored = StoredData.new
|
327
|
+
unless @storages[params.hash_name]
|
328
|
+
return send_data("SERVER_ERROR #{params.hash_name} dose not exists.\r\n")
|
329
|
+
end
|
330
|
+
|
331
|
+
stored.vn, stored.last, stored.clk, stored.expt, stored.value =
|
332
|
+
@storages[params.hash_name].get_raw(params.vn, params.key, params.digest)
|
333
|
+
stored = nil if stored.vn == nil || Time.now.to_i > stored.expt
|
334
|
+
ctx = CommandContext.new(s, params, stored)
|
335
|
+
instance_exec(ctx, &block)
|
336
|
+
rescue ClientErrorException => e
|
337
|
+
send_data("CLIENT_ERROR #{e.message}\r\n")
|
338
|
+
rescue ServerErrorException => e
|
339
|
+
send_data("SERVER_ERROR #{e.message}\r\n")
|
340
|
+
rescue LocalJumpError => e
|
341
|
+
@log.warn("#{e} #{$@}")
|
342
|
+
e.exit_value
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end # def_command_with_key_value
|
346
|
+
|
347
|
+
end # module ClassMethods
|
348
|
+
|
349
|
+
#
|
350
|
+
def forward_and_one_line_receive(nid, rs, data = nil)
|
351
|
+
if rs.last == "forward"
|
352
|
+
return send_data("SERVER_ERROR Routing table is inconsistent.\r\n")
|
353
|
+
end
|
354
|
+
|
355
|
+
@log.warn("forward #{rs} to #{nid}");
|
356
|
+
|
357
|
+
buf = rs.join(' ') + " forward\r\n"
|
358
|
+
buf << data + "\r\n" if data
|
359
|
+
res = send_cmd(nid, buf)
|
360
|
+
if res == nil || res.start_with?("ERROR")
|
361
|
+
return send_data("SERVER_ERROR Message forward failed.\r\n")
|
362
|
+
end
|
363
|
+
send_data("#{res}\r\n")
|
364
|
+
end
|
365
|
+
|
366
|
+
#
|
367
|
+
def forward_and_multi_line_receive(nid, rs, data=nil)
|
368
|
+
if rs.last == "forward"
|
369
|
+
return send_data("SERVER_ERROR Routing table is inconsistent.\r\n")
|
370
|
+
end
|
371
|
+
|
372
|
+
@log.warn("forward #{rs} to #{nid}");
|
373
|
+
|
374
|
+
buf = rs.join(' ') + " forward\r\n"
|
375
|
+
buf << data + "\r\n" if data
|
376
|
+
|
377
|
+
con = get_connection(nid)
|
378
|
+
con.send(buf)
|
379
|
+
|
380
|
+
buf = con.gets
|
381
|
+
if buf == nil
|
382
|
+
@rttable.proc_failed(nid)
|
383
|
+
@log.error("forward get failed:nid=#{nid} rs=#{rs} #{$@}")
|
384
|
+
return send_data("SERVER_ERROR Message forward failed.\r\n")
|
385
|
+
elsif buf.start_with?("ERROR")
|
386
|
+
@rttable.proc_succeed(nid)
|
387
|
+
con.close_connection
|
388
|
+
@log.error("forward get failed:nid=#{nid} rs=#{rs} #{$@}")
|
389
|
+
return send_data("SERVER_ERROR Message forward failed.\r\n")
|
390
|
+
elsif buf.start_with?("VALUE") == false
|
391
|
+
return_connection(nid, con)
|
392
|
+
@rttable.proc_succeed(nid)
|
393
|
+
return send_data(buf)
|
394
|
+
end
|
395
|
+
|
396
|
+
res = ''
|
397
|
+
begin
|
398
|
+
res << buf
|
399
|
+
s = buf.split(/ /)
|
400
|
+
if s[0] != 'VALUE'
|
401
|
+
return_connection(nid, con)
|
402
|
+
@rttable.proc_succeed(nid)
|
403
|
+
return send_data(buf)
|
404
|
+
end
|
405
|
+
res << con.read_bytes(s[3].to_i + 2)
|
406
|
+
end while (buf = con.gets)!="END\r\n"
|
407
|
+
|
408
|
+
res << "END\r\n"
|
409
|
+
|
410
|
+
return_connection(nid, con)
|
411
|
+
@rttable.proc_succeed(nid)
|
412
|
+
|
413
|
+
send_data(res)
|
414
|
+
rescue => e
|
415
|
+
@rttable.proc_failed(nid) if e.message != "no connection"
|
416
|
+
@log.error("forward get failed:nid=#{nid} rs=#{rs} #{e} #{$@}")
|
417
|
+
send_data("SERVER_ERROR Message forward failed.\r\n")
|
418
|
+
end
|
419
|
+
|
420
|
+
end # module Definition
|
421
|
+
end # module Command
|
422
|
+
end # module Roma
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'roma/stats'
|
3
|
+
require 'roma/command/util_command_receiver'
|
4
|
+
require 'roma/command/command_definition'
|
5
|
+
|
6
|
+
module Roma
|
7
|
+
module Command
|
8
|
+
|
9
|
+
module MultiHashCommandReceiver
|
10
|
+
include Roma::Command::Definition
|
11
|
+
|
12
|
+
# defhash <name>
|
13
|
+
def_command_with_relay :defhash do |s|
|
14
|
+
if s.length != 2
|
15
|
+
"#{@defhash}"
|
16
|
+
else
|
17
|
+
unless @storages.key?(s[1])
|
18
|
+
raise(Roma::Command::Definition::ClientErrorException,
|
19
|
+
"#{s[1]} dose not find.")
|
20
|
+
end
|
21
|
+
@defhash = s[1]
|
22
|
+
"STORED"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# mounthash <name>
|
27
|
+
def_command_with_relay :mounthash do |s|
|
28
|
+
if s.length != 2
|
29
|
+
raise(Roma::Command::Definition::ClientErrorException,
|
30
|
+
"usage:mounthash <name>")
|
31
|
+
end
|
32
|
+
if @storages.key?(s[1])
|
33
|
+
raise(Roma::Command::Definition::ServerErrorException,
|
34
|
+
"#{s[1]} already mounted.")
|
35
|
+
end
|
36
|
+
# check a directory existence
|
37
|
+
unless File.directory? "#{Config::STORAGE_PATH}/#{@stats.ap_str}/#{s[1]}"
|
38
|
+
raise(Roma::Command::Definition::ServerErrorException,
|
39
|
+
"#{s[1]} dose not find.")
|
40
|
+
end
|
41
|
+
createhash(s[1], 'MOUNTED')
|
42
|
+
end
|
43
|
+
|
44
|
+
# umounthash <name>
|
45
|
+
def_command_with_relay :umounthash do |s|
|
46
|
+
if s.length != 2
|
47
|
+
raise(Roma::Command::Definition::ClientErrorException,
|
48
|
+
"usage:umounthash <name>")
|
49
|
+
end
|
50
|
+
unless @storages.key?(s[1])
|
51
|
+
raise(Roma::Command::Definition::ServerErrorException,
|
52
|
+
"#{s[1]} dose not find.")
|
53
|
+
end
|
54
|
+
umounthash(s[1])
|
55
|
+
end
|
56
|
+
|
57
|
+
# createhash <name>
|
58
|
+
def_command_with_relay :createhash do |s|
|
59
|
+
if s.length != 2
|
60
|
+
raise(Roma::Command::Definition::ClientErrorException,
|
61
|
+
"usage:createhash <name>")
|
62
|
+
end
|
63
|
+
createhash(s[1], 'CREATED')
|
64
|
+
end
|
65
|
+
|
66
|
+
# deletehash <name>
|
67
|
+
def_command_with_relay :deletehash do |s|
|
68
|
+
if s.length != 2
|
69
|
+
raise(Roma::Command::Definition::ClientErrorException,
|
70
|
+
"usage:deletehash <name>")
|
71
|
+
end
|
72
|
+
deletehash(s[1])
|
73
|
+
end
|
74
|
+
|
75
|
+
# hashlist
|
76
|
+
def ev_hashlist(s)
|
77
|
+
send_data("#{@storages.keys.join ' '}\r\n")
|
78
|
+
end
|
79
|
+
|
80
|
+
def createhash(hname, msg)
|
81
|
+
if @storages.key?(hname)
|
82
|
+
return "SERVER_ERROR #{hname} already exists."
|
83
|
+
end
|
84
|
+
st = Config::STORAGE_CLASS.new
|
85
|
+
st.storage_path = "#{Config::STORAGE_PATH}/#{@stats.ap_str}/#{hname}"
|
86
|
+
st.vn_list = @rttable.vnodes
|
87
|
+
st.divnum = Config::STORAGE_DIVNUM
|
88
|
+
st.option = Config::STORAGE_OPTION
|
89
|
+
@storages[hname] = st
|
90
|
+
@storages[hname].opendb
|
91
|
+
@log.info("createhash #{hname}")
|
92
|
+
return msg
|
93
|
+
rescue =>e
|
94
|
+
@log.error("#{e} #{$@}")
|
95
|
+
"NOT #{msg}"
|
96
|
+
end
|
97
|
+
private :createhash
|
98
|
+
|
99
|
+
def deletehash(hname)
|
100
|
+
ret = umounthash(hname)
|
101
|
+
return ret if ret != 'UNMOUNTED'
|
102
|
+
FileUtils.rm_rf "#{Config::STORAGE_PATH}/#{@stats.ap_str}/#{hname}"
|
103
|
+
@log.info("deletehash #{hname}")
|
104
|
+
return "DELETED"
|
105
|
+
rescue =>e
|
106
|
+
@log.error("#{e}")
|
107
|
+
end
|
108
|
+
private :deletehash
|
109
|
+
|
110
|
+
def umounthash(hname)
|
111
|
+
if @defhash == hname
|
112
|
+
return "SERVER_ERROR default hash can't unmount."
|
113
|
+
end
|
114
|
+
unless @storages.key?(hname)
|
115
|
+
return "SERVER_ERROR #{hname} dose not exists."
|
116
|
+
end
|
117
|
+
st = @storages[hname]
|
118
|
+
@storages.delete(hname)
|
119
|
+
st.closedb
|
120
|
+
"UNMOUNTED"
|
121
|
+
end
|
122
|
+
private :umounthash
|
123
|
+
|
124
|
+
end # MultiHashCommandReceiver
|
125
|
+
|
126
|
+
end # module Command
|
127
|
+
end # module Roma
|