roma 0.8.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +19 -0
- data/ruby/server/lib/roma/async_process.rb +130 -16
- data/ruby/server/lib/roma/command/command_definition.rb +19 -3
- data/ruby/server/lib/roma/command/rt_command_receiver.rb +28 -0
- data/ruby/server/lib/roma/command/sys_command_receiver.rb +64 -2
- data/ruby/server/lib/roma/config.rb +1 -0
- data/ruby/server/lib/roma/plugin/plugin_gui.rb +66 -0
- data/ruby/server/lib/roma/plugin/plugin_storage.rb +49 -6
- data/ruby/server/lib/roma/romad.rb +23 -18
- data/ruby/server/lib/roma/routing/cb_rttable.rb +28 -10
- data/ruby/server/lib/roma/routing/random_partitioner.rb +34 -7
- data/ruby/server/lib/roma/routing/rttable.rb +24 -7
- data/ruby/server/lib/roma/stats.rb +11 -1
- data/ruby/server/lib/roma/storage/basic_storage.rb +36 -31
- data/ruby/server/lib/roma/tools/cpdb.rb +20 -2
- data/ruby/server/lib/roma/tools/safecopy_integration_test.rb +37 -16
- data/ruby/server/lib/roma/version.rb +1 -1
- data/ruby/server/test/t_protocol.rb +1 -1
- data/ruby/server/test/t_storage.rb +28 -21
- data/ruby/server/test/t_writebehind.rb +120 -5
- metadata +19 -18
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Roma
|
4
|
+
module CommandPlugin
|
5
|
+
|
6
|
+
module PluginGui
|
7
|
+
include ::Roma::CommandPlugin
|
8
|
+
|
9
|
+
# get_routing_history
|
10
|
+
def ev_get_routing_history(s)
|
11
|
+
routing_path = get_config_stat["config.RTTABLE_PATH"]
|
12
|
+
f_list = Dir.glob("#{routing_path}/*")
|
13
|
+
contents = ""
|
14
|
+
f_list.each{|fname|
|
15
|
+
contents << File.read(fname)
|
16
|
+
}
|
17
|
+
routing_list = contents.scan(/[-\.a-zA-Z\d]+_[\d]+/).uniq.sort
|
18
|
+
routing_list.each{|routing|
|
19
|
+
send_data("#{routing}\r\n")
|
20
|
+
}
|
21
|
+
send_data("END\r\n")
|
22
|
+
end
|
23
|
+
|
24
|
+
# get_logs [line count]
|
25
|
+
def ev_gather_logs(s)
|
26
|
+
if s.length != 2
|
27
|
+
return send_data("CLIENT_ERROR number of arguments (#{s.length-1} for 1)\r\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
line_count = s[1].to_i
|
31
|
+
if line_count < 1 || line_count > 100
|
32
|
+
return send_data("CLIENT_ERROR line counts is restricted to between 1-100 lines\r\n")
|
33
|
+
end
|
34
|
+
|
35
|
+
if @stats.gui_run_gather_logs
|
36
|
+
return send_data("CLIENT_ERROR gathering process is already going\r\n")
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
@stats.gui_run_gather_logs = true
|
41
|
+
Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('start_get_logs', [line_count]))
|
42
|
+
|
43
|
+
send_data("STARTED\r\n")
|
44
|
+
rescue
|
45
|
+
@stats.gui_run_gather_logs = false
|
46
|
+
@rttable.logs = []
|
47
|
+
send_data("CLIENT_ERROR\r\n")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# show_logs
|
52
|
+
def ev_show_logs(s)
|
53
|
+
if @stats.gui_run_gather_logs
|
54
|
+
send_data("Not finished gathering\r\n")
|
55
|
+
else
|
56
|
+
@rttable.logs.each{|log|
|
57
|
+
send_data(log)
|
58
|
+
}
|
59
|
+
send_data("END\r\n")
|
60
|
+
@rttable.logs.clear
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end # end of module PluginGui
|
65
|
+
end # end of module CommandPlugin
|
66
|
+
end # end of modlue Roma
|
@@ -141,6 +141,12 @@ module Roma
|
|
141
141
|
send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
|
142
142
|
return
|
143
143
|
end
|
144
|
+
|
145
|
+
if @stats.wb_command_map.key?(:delete__prev)
|
146
|
+
data = @storages[hname].get(vn, key, d)
|
147
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:delete__prev], key, data) if data
|
148
|
+
end
|
149
|
+
|
144
150
|
res = @storages[hname].delete(vn, key, d)
|
145
151
|
@stats.delete_count += 1
|
146
152
|
|
@@ -177,6 +183,12 @@ module Roma
|
|
177
183
|
send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
|
178
184
|
return
|
179
185
|
end
|
186
|
+
|
187
|
+
if @stats.wb_command_map.key?(:delete__prev)
|
188
|
+
data = @storages[hname].get(vn, key, d)
|
189
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:delete__prev], key, data) if data
|
190
|
+
end
|
191
|
+
|
180
192
|
res = @storages[hname].delete(vn, key, d)
|
181
193
|
@stats.delete_count += 1
|
182
194
|
|
@@ -311,12 +323,20 @@ module Roma
|
|
311
323
|
return
|
312
324
|
end
|
313
325
|
|
326
|
+
if @stats.wb_command_map.key?(:set_expt__prev)
|
327
|
+
@log.debug(":set_export__prev")
|
328
|
+
# [vn, t, clk, expt, val]
|
329
|
+
data = @storages[hname].get_raw(vn, key, d)
|
330
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt__prev], key, data[3].to_s) if data
|
331
|
+
end
|
332
|
+
|
314
333
|
expt = chg_time_expt(s[2].to_i)
|
315
334
|
ret = @storages[hname].set_expt(vn, key, d, expt)
|
316
335
|
|
317
336
|
if ret
|
318
|
-
if @stats.wb_command_map.key?(:
|
319
|
-
|
337
|
+
if @stats.wb_command_map.key?(:set_expt)
|
338
|
+
@log.debug(":set_export")
|
339
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt], key, expt.to_s)
|
320
340
|
end
|
321
341
|
redundant(nodes[1..-1], hname, key, d, ret[2], ret[3], ret[4])
|
322
342
|
send_data("STORED\r\n")
|
@@ -342,12 +362,18 @@ module Roma
|
|
342
362
|
return
|
343
363
|
end
|
344
364
|
|
365
|
+
if @stats.wb_command_map.key?(:set_expt__prev)
|
366
|
+
# [vn, t, clk, expt, val]
|
367
|
+
data = @storages[hname].get_raw(vn, key, d)
|
368
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt__prev], key, data[3].to_s) if data
|
369
|
+
end
|
370
|
+
|
345
371
|
expt = chg_time_expt(s[2].to_i)
|
346
372
|
ret = @storages[hname].set_expt(vn, key, d, expt)
|
347
373
|
|
348
374
|
if ret
|
349
|
-
if @stats.wb_command_map.key?(:
|
350
|
-
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt],
|
375
|
+
if @stats.wb_command_map.key?(:set_expt)
|
376
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt], key, expt.to_s)
|
351
377
|
end
|
352
378
|
redundant(nodes[1..-1], hname, key, d, ret[2], ret[3], ret[4])
|
353
379
|
send_data("STORED\r\n")
|
@@ -431,6 +457,12 @@ module Roma
|
|
431
457
|
send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
|
432
458
|
return
|
433
459
|
end
|
460
|
+
|
461
|
+
if @stats.wb_command_map.key?("#{fnc.to_s}__prev".to_sym)
|
462
|
+
data = @storages[hname].get(vn, k, d)
|
463
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map["#{fnc.to_s}__prev".to_sym], k, data) if data
|
464
|
+
end
|
465
|
+
|
434
466
|
ret = @storages[hname].send(fnc, vn, k, d, expt ,v)
|
435
467
|
@stats.write_count += 1
|
436
468
|
|
@@ -453,6 +485,11 @@ module Roma
|
|
453
485
|
return
|
454
486
|
end
|
455
487
|
|
488
|
+
if @stats.wb_command_map.key?(:cas__prev)
|
489
|
+
data = @storages[hname].get(vn, k, d)
|
490
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:cas__prev], k, data) if data
|
491
|
+
end
|
492
|
+
|
456
493
|
ret = @storages[hname].cas(vn, k, d, clk, expt ,v)
|
457
494
|
@stats.write_count += 1
|
458
495
|
|
@@ -507,8 +544,8 @@ module Roma
|
|
507
544
|
|
508
545
|
bytes = s[4].to_i
|
509
546
|
if bytes < 0
|
510
|
-
@log.error("set:wrong
|
511
|
-
return send_data("CLIENT_ERROR Wrong
|
547
|
+
@log.error("set:wrong value size(#{s})")
|
548
|
+
return send_data("CLIENT_ERROR Wrong value size.\r\n")
|
512
549
|
end
|
513
550
|
|
514
551
|
key,hname = s[1].split("\e")
|
@@ -553,6 +590,12 @@ module Roma
|
|
553
590
|
send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
|
554
591
|
return
|
555
592
|
end
|
593
|
+
|
594
|
+
if @stats.wb_command_map.key?("#{fnc.to_s}__prev".to_sym)
|
595
|
+
data = @storages[hname].get(vn, k, d)
|
596
|
+
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map["#{fnc.to_s}__prev".to_sym], k, data) if data
|
597
|
+
end
|
598
|
+
|
556
599
|
res = @storages[hname].send(fnc, vn, k, d, v)
|
557
600
|
@stats.write_count += 1
|
558
601
|
|
@@ -13,7 +13,7 @@ require 'roma/routing/cb_rttable'
|
|
13
13
|
require 'timeout'
|
14
14
|
|
15
15
|
module Roma
|
16
|
-
|
16
|
+
|
17
17
|
class Romad
|
18
18
|
include AsyncProcess
|
19
19
|
include WriteBehindProcess
|
@@ -49,7 +49,7 @@ module Roma
|
|
49
49
|
@storages.each{|hashname,st|
|
50
50
|
st.opendb
|
51
51
|
}
|
52
|
-
|
52
|
+
|
53
53
|
start_async_process
|
54
54
|
start_wb_process
|
55
55
|
timer
|
@@ -84,7 +84,7 @@ module Roma
|
|
84
84
|
Event::Handler::connections.clear
|
85
85
|
|
86
86
|
EventMachine::run do
|
87
|
-
EventMachine.start_server('0.0.0.0', @stats.port,
|
87
|
+
EventMachine.start_server('0.0.0.0', @stats.port,
|
88
88
|
Roma::Command::Receiver,
|
89
89
|
@storages, @rttable)
|
90
90
|
# a management of connections lives
|
@@ -109,7 +109,7 @@ module Roma
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
}
|
112
|
-
dellist.each{|k|
|
112
|
+
dellist.each{|k|
|
113
113
|
@log.info("delete connection lastcmd = #{k.lastcmd}")
|
114
114
|
Event::Handler::connections.delete(k)
|
115
115
|
}
|
@@ -194,7 +194,7 @@ module Roma
|
|
194
194
|
|
195
195
|
def initialize_wb_writer
|
196
196
|
@wb_writer = Roma::WriteBehind::FileWriter.new(
|
197
|
-
Roma::Config::WRITEBEHIND_PATH,
|
197
|
+
Roma::Config::WRITEBEHIND_PATH,
|
198
198
|
Roma::Config::WRITEBEHIND_SHIFT_SIZE,
|
199
199
|
@log)
|
200
200
|
end
|
@@ -223,7 +223,7 @@ module Roma
|
|
223
223
|
Event::Handler.class_eval{
|
224
224
|
alias gets2 gets
|
225
225
|
undef gets
|
226
|
-
|
226
|
+
|
227
227
|
def gets
|
228
228
|
ret = gets2
|
229
229
|
@log.info("command log:#{ret.chomp}") if ret
|
@@ -231,7 +231,7 @@ module Roma
|
|
231
231
|
end
|
232
232
|
}
|
233
233
|
end
|
234
|
-
|
234
|
+
|
235
235
|
if @stats.join_ap
|
236
236
|
Command::Receiver::mk_evlist
|
237
237
|
else
|
@@ -280,7 +280,7 @@ module Roma
|
|
280
280
|
opts.on_tail("-v", "--version", "Show version") {
|
281
281
|
puts "romad.rb #{Roma::VERSION}"; exit
|
282
282
|
}
|
283
|
-
|
283
|
+
|
284
284
|
opts.on("-n", "--name [name]") { |v| @stats.name = v }
|
285
285
|
|
286
286
|
@stats.enabled_repetition_host_in_routing = false
|
@@ -311,7 +311,7 @@ module Roma
|
|
311
311
|
unless @stats.port =~ /^\d+$/
|
312
312
|
raise OptionParser::ParseError.new('Port number is not numeric.')
|
313
313
|
end
|
314
|
-
|
314
|
+
|
315
315
|
@stats.join_ap.sub!(':','_') if @stats.join_ap
|
316
316
|
if @stats.join_ap && !(@stats.join_ap =~ /^.+_\d+$/)
|
317
317
|
raise OptionParser::ParseError.new('[address:port] can not parse.')
|
@@ -327,7 +327,7 @@ module Roma
|
|
327
327
|
if Config.const_defined? :STORAGE_PATH
|
328
328
|
path = "#{Roma::Config::STORAGE_PATH}/#{@stats.ap_str}"
|
329
329
|
end
|
330
|
-
|
330
|
+
|
331
331
|
if Config.const_defined? :STORAGE_CLASS
|
332
332
|
st_class = Config::STORAGE_CLASS
|
333
333
|
end
|
@@ -379,11 +379,11 @@ module Roma
|
|
379
379
|
@rttable = Roma::Routing::ChurnbasedRoutingTable.new(rd,fname)
|
380
380
|
end
|
381
381
|
end
|
382
|
-
|
382
|
+
|
383
383
|
if Roma::Config.const_defined?(:RTTABLE_SUB_NID)
|
384
384
|
@rttable.sub_nid = Roma::Config::RTTABLE_SUB_NID
|
385
385
|
end
|
386
|
-
|
386
|
+
|
387
387
|
if Roma::Config.const_defined?(:ROUTING_FAIL_CNT_THRESHOLD)
|
388
388
|
@rttable.fail_cnt_threshold = Roma::Config::ROUTING_FAIL_CNT_THRESHOLD
|
389
389
|
end
|
@@ -413,6 +413,11 @@ module Roma
|
|
413
413
|
@log.error("AUTO_RECOVER is off or Unavailable value is set to [DEFAULT_LOST_ACTION] => #{@rttable.lost_action}")
|
414
414
|
end
|
415
415
|
}
|
416
|
+
|
417
|
+
if Roma::Config.const_defined?(:ROUTING_EVENT_LIMIT_LINE)
|
418
|
+
@rttable.event_limit_line = Roma::Config::ROUTING_EVENT_LIMIT_LINE
|
419
|
+
end
|
420
|
+
Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('start_get_routing_event'))
|
416
421
|
end
|
417
422
|
|
418
423
|
def initialize_rttable_join
|
@@ -490,7 +495,7 @@ module Roma
|
|
490
495
|
Messaging::ConPool.instance.return_connection(nid,con)
|
491
496
|
rcv
|
492
497
|
rescue Exception
|
493
|
-
nil
|
498
|
+
nil
|
494
499
|
end
|
495
500
|
|
496
501
|
def timer
|
@@ -631,11 +636,11 @@ module Roma
|
|
631
636
|
@stats.run_sync_routing = false
|
632
637
|
}
|
633
638
|
t[:name] = 'sync_routing'
|
634
|
-
end
|
639
|
+
end
|
635
640
|
|
636
641
|
def routing_hash_comparison(nid,id='0')
|
637
642
|
return :skip if @stats.run_join || @stats.run_recover || @stats.run_balance
|
638
|
-
|
643
|
+
|
639
644
|
h = async_send_cmd(nid,"mklhash #{id}\r\n")
|
640
645
|
if h && h.start_with?("ERROR") == false && @rttable.mtree.get(id) != h
|
641
646
|
if (id.length - 1) == @rttable.div_bits
|
@@ -652,12 +657,12 @@ module Roma
|
|
652
657
|
def sync_routing(nid,id)
|
653
658
|
vn = @rttable.mtree.to_vn(id)
|
654
659
|
@log.warn("vn=#{vn} inconsistent")
|
655
|
-
|
660
|
+
|
656
661
|
res = async_send_cmd(nid,"getroute #{vn}\r\n")
|
657
662
|
return if res == nil || res.start_with?("ERROR")
|
658
663
|
clk,*nids = res.split(' ')
|
659
664
|
clk = @rttable.set_route(vn, clk.to_i, nids)
|
660
|
-
|
665
|
+
|
661
666
|
if clk.is_a?(Integer) == false
|
662
667
|
clk,nids = @rttable.search_nodes_with_clk(vn)
|
663
668
|
cmd = "setroute #{vn} #{clk-1}"
|
@@ -715,7 +720,7 @@ module Roma
|
|
715
720
|
@log.error("#{e}\n#{$@}")
|
716
721
|
nil
|
717
722
|
end
|
718
|
-
|
723
|
+
|
719
724
|
def stop
|
720
725
|
@storages.each_value{|st|
|
721
726
|
st.closedb
|
@@ -19,6 +19,9 @@ module Roma
|
|
19
19
|
attr_accessor :auto_recover
|
20
20
|
attr_accessor :auto_recover_status
|
21
21
|
attr_accessor :auto_recover_time
|
22
|
+
attr_accessor :event
|
23
|
+
attr_accessor :event_limit_line
|
24
|
+
attr_accessor :logs
|
22
25
|
attr_reader :version_of_nodes
|
23
26
|
attr_reader :min_version
|
24
27
|
|
@@ -34,6 +37,9 @@ module Roma
|
|
34
37
|
@auto_recover=false
|
35
38
|
@auto_recover_status="waiting"
|
36
39
|
@auto_recover_time=1800
|
40
|
+
@event = []
|
41
|
+
@event_limit_line = 1000
|
42
|
+
@logs = []
|
37
43
|
@enabled_failover=false
|
38
44
|
@lock = Mutex.new
|
39
45
|
@version_of_nodes = Hash.new(0)
|
@@ -47,11 +53,13 @@ module Roma
|
|
47
53
|
ret['routing.auto_recover'] = @auto_recover.to_s
|
48
54
|
ret['routing.auto_recover_status'] = @auto_recover_status.to_s
|
49
55
|
ret['routing.auto_recover_time'] = @auto_recover_time
|
56
|
+
ret['routing.event'] = @event
|
57
|
+
ret['routing.event_limit_line'] = @event_limit_line
|
50
58
|
ret['routing.version_of_nodes'] = @version_of_nodes.inspect
|
51
59
|
ret['routing.min_version'] = @min_version
|
52
60
|
ret
|
53
61
|
end
|
54
|
-
|
62
|
+
|
55
63
|
def set_version(nid,ver)
|
56
64
|
@version_of_nodes[nid] = ver
|
57
65
|
@min_version = find_min_version
|
@@ -64,11 +72,11 @@ module Roma
|
|
64
72
|
end
|
65
73
|
|
66
74
|
def set_leave_proc(&block)
|
67
|
-
@leave_proc=block
|
75
|
+
@leave_proc=block
|
68
76
|
end
|
69
77
|
|
70
78
|
def set_lost_proc(&block)
|
71
|
-
@lost_proc=block
|
79
|
+
@lost_proc=block
|
72
80
|
end
|
73
81
|
|
74
82
|
def set_recover_proc(&block)
|
@@ -86,13 +94,13 @@ module Roma
|
|
86
94
|
@log_name="#{@fname}.#{log_list.last[0]+1}"
|
87
95
|
end
|
88
96
|
end
|
89
|
-
@log_fd=File.open(@log_name,"a")
|
97
|
+
@log_fd=File.open(@log_name,"a")
|
90
98
|
end
|
91
99
|
|
92
100
|
def write_log_setroute(vn, clk, nids)
|
93
101
|
log="setroute #{vn} #{clk}"
|
94
102
|
nids.each{ |nid| log << " #{nid}" }
|
95
|
-
write_log(log)
|
103
|
+
write_log(log)
|
96
104
|
end
|
97
105
|
|
98
106
|
def write_log(line)
|
@@ -119,7 +127,7 @@ module Roma
|
|
119
127
|
buf = self.nodes
|
120
128
|
buf.delete(ap_str)
|
121
129
|
hosts = []
|
122
|
-
|
130
|
+
|
123
131
|
unless rep_host
|
124
132
|
buf.each{ |node|
|
125
133
|
host = node.split(/[:_]/)[0]
|
@@ -128,7 +136,7 @@ module Roma
|
|
128
136
|
else
|
129
137
|
hosts = buf
|
130
138
|
end
|
131
|
-
|
139
|
+
|
132
140
|
hosts.length < @rd.rn
|
133
141
|
end
|
134
142
|
|
@@ -168,7 +176,7 @@ module Roma
|
|
168
176
|
end
|
169
177
|
}
|
170
178
|
idx = short_idx if short_idx.length > 0
|
171
|
-
|
179
|
+
|
172
180
|
ks = idx.keys
|
173
181
|
return nil if ks.length == 0
|
174
182
|
vn = ks[rand(ks.length)]
|
@@ -205,6 +213,7 @@ module Roma
|
|
205
213
|
@rd.nodes << nid
|
206
214
|
@rd.nodes.sort!
|
207
215
|
write_log("join #{nid}")
|
216
|
+
set_event(nid, 'join')
|
208
217
|
end
|
209
218
|
end
|
210
219
|
|
@@ -227,10 +236,11 @@ module Roma
|
|
227
236
|
@rd.nodes.delete(nid)
|
228
237
|
@version_of_nodes.delete(nid)
|
229
238
|
@min_version = find_min_version
|
230
|
-
|
239
|
+
|
231
240
|
@log.warn("#{nid} just failed.")
|
232
241
|
write_log("leave #{nid}")
|
233
|
-
|
242
|
+
set_event(nid, __method__)
|
243
|
+
|
234
244
|
lost_vnodes=[]
|
235
245
|
short_vnodes=[]
|
236
246
|
@lock.synchronize {
|
@@ -261,6 +271,14 @@ module Roma
|
|
261
271
|
@fail_cnt.delete(nid)
|
262
272
|
end
|
263
273
|
|
274
|
+
def set_event(nid, process)
|
275
|
+
t = Time.now
|
276
|
+
tstr = "#{t.strftime('%Y-%m-%dT%H:%M:%S')}.#{t.usec}"
|
277
|
+
@event.shift if @event.size >= @event_limit_line
|
278
|
+
@event << ("#{tstr} #{process} #{nid}")
|
279
|
+
end
|
280
|
+
private :set_event
|
281
|
+
|
264
282
|
def set_route_and_inc_clk_inside_sync(vn, nodes)
|
265
283
|
@rd.v_idx[vn] = nodes
|
266
284
|
clk = @rd.v_clk[vn] + 1
|