roma 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +44 -1
- data/Gemfile.lock +18 -15
- data/README.md +15 -1
- data/bin/consistency_test +10 -0
- data/bin/data_accumulation +11 -0
- data/lib/roma/async_process.rb +39 -2
- data/lib/roma/command/sys_command_receiver.rb +80 -0
- data/lib/roma/command/vn_command_receiver.rb +1 -1
- data/lib/roma/config.rb +1 -1
- data/lib/roma/plugin/plugin_storage.rb +105 -1
- data/lib/roma/romad.rb +13 -1
- data/lib/roma/routing/cb_rttable.rb +1 -1
- data/lib/roma/tools/consistency_test.rb +77 -0
- data/lib/roma/tools/data_accumulation.rb +64 -0
- data/lib/roma/version.rb +1 -1
- data/lib/roma/write_behind.rb +138 -1
- data/test/config4mhash.rb +1 -1
- data/test/config4storage_error.rb +1 -1
- data/test/config4test.rb +1 -1
- data/test/cpdbtest/config4cpdb_base.rb +1 -1
- data/test/optional_test/t_mkroute_rich.rb +44 -0
- data/test/optional_test/t_other_cpdb.rb +45 -0
- data/test/optional_test/t_other_database.rb +59 -0
- data/test/{t_routing_logic.rb → optional_test/t_routing_logic.rb} +1 -0
- data/test/roma-test-storage.rb +685 -0
- data/test/roma-test-utils.rb +24 -0
- data/test/run-test.rb +9 -0
- data/test/t_command_definition.rb +2 -0
- data/test/t_cpdata.rb +1 -0
- data/test/t_cpdb.rb +22 -34
- data/test/t_eventmachine.rb +1 -0
- data/test/t_listplugin.rb +2 -0
- data/test/t_logshift.rb +2 -4
- data/test/t_mapcountplugin.rb +48 -37
- data/test/t_mapplugin.rb +2 -0
- data/test/t_mhash.rb +2 -1
- data/test/t_new_func.rb +386 -0
- data/test/t_protocol.rb +66 -1
- data/test/t_rclient.rb +2 -0
- data/test/t_replication.rb +299 -0
- data/test/t_routing_data.rb +6 -5
- data/test/t_storage.rb +5 -740
- data/test/t_storage_error.rb +1 -0
- data/test/t_writebehind.rb +11 -2
- metadata +31 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ad632c67885c4aaf13b8fdec745d45bbcd94feb
|
4
|
+
data.tar.gz: 9c5967e28f0ae8f250223b1e4d81852ad0723c38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 343240d35ac31586f4325ac5f2b78de0e69b19a96684b76fff5ac0df0aa032eef53287283a35701b77d8ba6f06a8d58ed0116216fd5e5210d60851631b1ac6ba
|
7
|
+
data.tar.gz: 99bd24be9e021ae43d7330b69f0b6935422d790165c04a934118d76b3672d8c3d35627ac0b888ade65ebc56291409c2dc0c53303c9dae7f23ca55341285cfcb1
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,47 @@
|
|
1
|
-
*1.
|
1
|
+
*1.3.0 (Jan 21 2016)*
|
2
|
+
|
3
|
+
* change unit test to pass in the poor env [hiroaki-iwase] f0d9cc8
|
4
|
+
|
5
|
+
*1.3.0RC1 (Nov 13 2015)*
|
6
|
+
|
7
|
+
* Update README.md [Paras Patel] 3350844
|
8
|
+
* automation some manual tests [hiroaki-iwase] dea72fa
|
9
|
+
* auto_recover
|
10
|
+
* set_routing_trans_timeout
|
11
|
+
* st_class
|
12
|
+
* adm_tool
|
13
|
+
* check_enable_repeathost
|
14
|
+
* check_replication _in_host
|
15
|
+
* add below func's unit test [hiroaki-iwase] f9a1721
|
16
|
+
* jaro-winkler
|
17
|
+
* stat log level
|
18
|
+
* stat secondary
|
19
|
+
* shutdown_self
|
20
|
+
* stat failover
|
21
|
+
* get_key_info
|
22
|
+
* enabled_repetition_in_routing?
|
23
|
+
* switch_dns_caching
|
24
|
+
* add_rttable_sub_nid
|
25
|
+
* delete_rttable_sub_nid
|
26
|
+
* clear_rttable_sub_nid
|
27
|
+
* del_latency_avg_calc_cmd
|
28
|
+
* add_latency_avg_calc_cmd
|
29
|
+
* chg_latency_avg_calc_time_count
|
30
|
+
* set_latency_avg_calc_rule
|
31
|
+
* add test of below func [hiroaki-iwase] 613c0d0
|
32
|
+
* stat log level
|
33
|
+
* stat secondary
|
34
|
+
* shutdown_self
|
35
|
+
* add unit test of jaro winkler [hiroaki-iwase] 22fd7b2
|
36
|
+
* remove puts method in testfile [hiroaki-iwase] cec8a6d
|
37
|
+
* implement cluster replication function [hiroaki-iwase] a1fa5e8
|
38
|
+
* implement get_expt command [hiroaki-iwase] 04f1a14
|
39
|
+
* change log level of push_a_vnode_stream from info to debug [hiroaki-iwase] e668fc0
|
40
|
+
* add how to contributing [hiroaki-iwase] 6d9945a
|
41
|
+
* add progress rate to data accumulation tool [hiroaki-iwase] 2f9d8aa
|
42
|
+
* implement consistency check tool [Hiroaki Iwase] 3211bd9
|
43
|
+
|
44
|
+
*1.2.0 (Aug 19 2015)*
|
2
45
|
|
3
46
|
* Change gemspec [Hiroaki Iwase] db2bb42
|
4
47
|
* Modify unit-test [Hiroaki Iwase] 7479034
|
data/Gemfile.lock
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
roma (1.
|
4
|
+
roma (1.3.0)
|
5
5
|
eventmachine (~> 1.0.0)
|
6
6
|
jaro_winkler (~> 1.3.5)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
archive-zip (0.
|
11
|
+
archive-zip (0.8.0)
|
12
12
|
io-like (~> 0.3.0)
|
13
|
-
eventmachine (1.0.
|
14
|
-
ffi (1.9.
|
15
|
-
gdbm (1.
|
13
|
+
eventmachine (1.0.9.1)
|
14
|
+
ffi (1.9.10)
|
15
|
+
gdbm (1.3.0)
|
16
16
|
gqtp (1.0.6)
|
17
|
-
groonga-client (0.1.
|
17
|
+
groonga-client (0.1.9)
|
18
18
|
gqtp (>= 1.0.4)
|
19
19
|
groonga-command (>= 1.0.8)
|
20
|
-
groonga-command (1.
|
20
|
+
groonga-command (1.1.5)
|
21
21
|
json
|
22
22
|
io-like (0.3.0)
|
23
|
-
jaro_winkler (1.3.
|
24
|
-
json (1.8.
|
25
|
-
pkg-config (1.1.
|
26
|
-
power_assert (0.2.
|
27
|
-
rake (10.
|
28
|
-
rroonga (
|
23
|
+
jaro_winkler (1.3.7)
|
24
|
+
json (1.8.3)
|
25
|
+
pkg-config (1.1.7)
|
26
|
+
power_assert (0.2.7)
|
27
|
+
rake (10.5.0)
|
28
|
+
rroonga (5.1.1)
|
29
29
|
archive-zip
|
30
30
|
groonga-client (>= 0.0.3)
|
31
31
|
json
|
32
32
|
pkg-config
|
33
|
-
sqlite3 (1.3.
|
34
|
-
test-unit (3.1.
|
33
|
+
sqlite3 (1.3.11)
|
34
|
+
test-unit (3.1.7)
|
35
35
|
power_assert
|
36
36
|
|
37
37
|
PLATFORMS
|
@@ -45,3 +45,6 @@ DEPENDENCIES
|
|
45
45
|
rroonga
|
46
46
|
sqlite3
|
47
47
|
test-unit
|
48
|
+
|
49
|
+
BUNDLED WITH
|
50
|
+
1.11.2
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# ROMA - A Distributed Key-Value Store in Ruby
|
1
|
+
# ROMA - A Distributed Key-Value Store in Ruby
|
2
2
|
|
3
3
|
ROMA is one of the data storing systems for distributed key-value stores.
|
4
4
|
It is a completely decentralized distributed system that consists of multiple
|
@@ -74,5 +74,19 @@ END
|
|
74
74
|
|
75
75
|
Refer to [Commands](http://roma-kvs.org/commands.html "Commands") for more detail information about ROMA Commands.
|
76
76
|
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
If you would like to contribute, please...
|
81
|
+
|
82
|
+
1. Fork.
|
83
|
+
2. Download [Ruby Client](https://github.com/roma/roma-ruby-client) to same directory.
|
84
|
+
3. Make changes in a branch & add unit tests.
|
85
|
+
4. Run Unit Test
|
86
|
+
* `ruby test/run_test.rb` (if unit test fails, run it again - it's fickle).
|
87
|
+
5. Create a pull request.
|
88
|
+
|
89
|
+
Contributions, improvements, comments and suggestions are welcome!
|
90
|
+
|
77
91
|
## Promoters
|
78
92
|
Roma is promoted by [Rakuten, Inc.](http://global.rakuten.com/corp/) and [Rakuten Institute of Technology](http://rit.rakuten.co.jp/).
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
base_path = Pathname(__FILE__).dirname.parent.expand_path
|
5
|
+
$LOAD_PATH.unshift("#{base_path}/lib")
|
6
|
+
|
7
|
+
client_base_path = Pathname(__FILE__).dirname.parent.parent.expand_path
|
8
|
+
$LOAD_PATH.unshift("#{client_base_path}/roma-ruby-client/lib")
|
9
|
+
|
10
|
+
require 'roma/tools/consistency_test'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
base_path = Pathname(__FILE__).dirname.parent.expand_path
|
5
|
+
$LOAD_PATH.unshift("#{base_path}/lib")
|
6
|
+
|
7
|
+
client_base_path = Pathname(__FILE__).dirname.parent.parent.expand_path
|
8
|
+
$LOAD_PATH.unshift("#{client_base_path}/roma-ruby-client/lib")
|
9
|
+
|
10
|
+
require 'roma/tools/data_accumulation'
|
11
|
+
|
data/lib/roma/async_process.rb
CHANGED
@@ -643,7 +643,7 @@ module Roma
|
|
643
643
|
end
|
644
644
|
|
645
645
|
def push_a_vnode_stream(hname, vn, nid)
|
646
|
-
@log.
|
646
|
+
@log.debug("#{__method__}:hname=#{hname} vn=#{vn} nid=#{nid}")
|
647
647
|
|
648
648
|
stop_clean_up
|
649
649
|
|
@@ -670,7 +670,7 @@ module Roma
|
|
670
670
|
con.write(data)
|
671
671
|
sleep @stats.stream_copy_wait_param
|
672
672
|
end
|
673
|
-
con.write("\0" * 20) # end of
|
673
|
+
con.write("\0" * 20) # end of stream
|
674
674
|
|
675
675
|
res = con.gets # STORED\r\n or error string
|
676
676
|
Roma::Messaging::ConPool.instance.return_connection(nid, con)
|
@@ -1043,5 +1043,42 @@ module Roma
|
|
1043
1043
|
|
1044
1044
|
get_point(f, target_time, type, latency_time, new_pos, target_pos)
|
1045
1045
|
end
|
1046
|
+
|
1047
|
+
def asyncev_start_replicate_existing_data_process(args)
|
1048
|
+
# args is [$roma.cr_writer.replica_rttable])
|
1049
|
+
t = Thread.new do
|
1050
|
+
begin
|
1051
|
+
$roma.cr_writer.run_existing_data_replication = true
|
1052
|
+
replicate_existing_data_process(args)
|
1053
|
+
rescue => e
|
1054
|
+
@log.error("#{__method__}:#{e.inspect} #{$ERROR_POSITION}")
|
1055
|
+
ensure
|
1056
|
+
$roma.cr_writer.run_existing_data_replication = false
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
t[:name] = __method__
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
def replicate_existing_data_process(args)
|
1063
|
+
@log.info("#{__method__} :start.")
|
1064
|
+
|
1065
|
+
@storages.each_key do |hname|
|
1066
|
+
@rttable.v_idx.each_key do |vn|
|
1067
|
+
raise unless $roma.cr_writer.run_existing_data_replication
|
1068
|
+
args[0].v_idx[vn].each do |replica_nid|
|
1069
|
+
res = push_a_vnode_stream(hname, vn, replica_nid)
|
1070
|
+
if res != 'STORED'
|
1071
|
+
@log.error("#{__method__}:push_a_vnode was failed:hname=#{hname} vn=#{vn}:#{res}")
|
1072
|
+
return false
|
1073
|
+
end
|
1074
|
+
end
|
1075
|
+
end
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
@log.info("#{__method__} has done.")
|
1079
|
+
rescue => e
|
1080
|
+
@log.error("#{e}\n#{$ERROR_POSITION}")
|
1081
|
+
end
|
1082
|
+
|
1046
1083
|
end # module AsyncProcess
|
1047
1084
|
end # module Roma
|
@@ -224,6 +224,86 @@ module Roma
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
|
+
# switch_replication command is change status of cluster replication
|
228
|
+
# if you want to activate, assign 1 nid(addr_port) of replication cluster as argument.
|
229
|
+
# if you want to copy existing data, add the 'all' after nid as argument
|
230
|
+
# switch_replication <true|false> [nid] [copy target]
|
231
|
+
def ev_switch_replication(s)
|
232
|
+
unless s.length.between?(2, 4)
|
233
|
+
return send_data("CLIENT_ERROR number of arguments\r\n")
|
234
|
+
end
|
235
|
+
unless s[1] =~ /^(true|false)$/
|
236
|
+
return send_data("CLIENT_ERROR value must be true or false\r\n")
|
237
|
+
end
|
238
|
+
if s[3] && s[3] != 'all'
|
239
|
+
return send_data("CLIENT_ERROR [copy target] must be all or nil\r\n")
|
240
|
+
end
|
241
|
+
|
242
|
+
res = broadcast_cmd("rswitch_replication #{s[1]} #{s[2]} #{s[3]}\r\n")
|
243
|
+
|
244
|
+
timeout(1){
|
245
|
+
case s[1]
|
246
|
+
when 'true'
|
247
|
+
$roma.cr_writer.update_mklhash(s[2])
|
248
|
+
$roma.cr_writer.update_nodelist(s[2])
|
249
|
+
$roma.cr_writer.update_rttable(s[2])
|
250
|
+
$roma.cr_writer.run_replication = true
|
251
|
+
if s[3] == 'all'
|
252
|
+
$roma.cr_writer.run_existing_data_replication = true
|
253
|
+
Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('start_replicate_existing_data_process', [$roma.cr_writer.replica_rttable]))
|
254
|
+
end
|
255
|
+
res[@stats.ap_str] = "ACTIVATED"
|
256
|
+
when 'false'
|
257
|
+
$roma.cr_writer.replica_mklhash = nil
|
258
|
+
$roma.cr_writer.replica_nodelist = []
|
259
|
+
$roma.cr_writer.replica_rttable = nil
|
260
|
+
$roma.cr_writer.run_replication = false
|
261
|
+
$roma.cr_writer.run_existing_data_replication = false
|
262
|
+
res[@stats.ap_str] = "DEACTIVATED"
|
263
|
+
end
|
264
|
+
}
|
265
|
+
send_data("#{res}\r\n")
|
266
|
+
rescue => e
|
267
|
+
send_data("#{e.class}: #{e}\r\n")
|
268
|
+
end
|
269
|
+
|
270
|
+
# rswitch_replication <true|false> [nid] [copy target]
|
271
|
+
def ev_rswitch_replication(s)
|
272
|
+
unless s.length.between?(2, 4)
|
273
|
+
return send_data("CLIENT_ERROR number of arguments\n\r")
|
274
|
+
end
|
275
|
+
unless s[1] =~ /^(true|false)$/
|
276
|
+
return send_data("CLIENT_ERROR value must be true or false\n\r")
|
277
|
+
end
|
278
|
+
if s[3] && s[3] != 'all'
|
279
|
+
return send_data("CLIENT_ERROR [copy target] must be all or nil\r\n")
|
280
|
+
end
|
281
|
+
|
282
|
+
timeout(1){
|
283
|
+
case s[1]
|
284
|
+
when 'true'
|
285
|
+
$roma.cr_writer.update_mklhash(s[2])
|
286
|
+
$roma.cr_writer.update_nodelist(s[2])
|
287
|
+
$roma.cr_writer.update_rttable(s[2])
|
288
|
+
$roma.cr_writer.run_replication = true
|
289
|
+
if s[3] == 'all'
|
290
|
+
$roma.cr_writer.run_existing_data_replication = true
|
291
|
+
Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('start_replicate_existing_data_process', [$roma.cr_writer.replica_rttable]))
|
292
|
+
end
|
293
|
+
send_data("ACTIVATED\r\n")
|
294
|
+
when 'false'
|
295
|
+
$roma.cr_writer.replica_mklhash = nil
|
296
|
+
$roma.cr_writer.replica_nodelist = []
|
297
|
+
$roma.cr_writer.replica_rttable = nil
|
298
|
+
$roma.cr_writer.run_replication = false
|
299
|
+
$roma.cr_writer.run_existing_data_replication = false
|
300
|
+
send_data("DEACTIVATED\r\n")
|
301
|
+
end
|
302
|
+
}
|
303
|
+
rescue => e
|
304
|
+
send_data("#{e.class}: #{e}\r\n")
|
305
|
+
end
|
306
|
+
|
227
307
|
# dcnice command is setting priority for a data-copy thread.
|
228
308
|
# a niceness of 1 is the highest priority and 5 is the lowest priority.
|
229
309
|
# dcnice <priority:1 to 5>
|
data/lib/roma/config.rb
CHANGED
@@ -126,6 +126,7 @@ module Roma
|
|
126
126
|
d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
|
127
127
|
vn = @rttable.get_vnode_id(d)
|
128
128
|
nodes = @rttable.search_nodes_for_write(vn)
|
129
|
+
|
129
130
|
if nodes[0] != @nid
|
130
131
|
cmd = "fdelete #{key}\e#{hname}"
|
131
132
|
s[2..-1].each{|c| cmd << " #{c}"}
|
@@ -137,6 +138,7 @@ module Roma
|
|
137
138
|
end
|
138
139
|
return send_data("#{res}\r\n")
|
139
140
|
end
|
141
|
+
|
140
142
|
unless @storages.key?(hname)
|
141
143
|
send_data("SERVER_ERROR #{hname} does not exists.\r\n")
|
142
144
|
return
|
@@ -165,6 +167,12 @@ module Roma
|
|
165
167
|
end
|
166
168
|
}
|
167
169
|
return send_data("NOT_FOUND\r\n") unless res[4]
|
170
|
+
|
171
|
+
if $roma.cr_writer.run_replication
|
172
|
+
fnc = 'delete'
|
173
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{s[1]}\r\n", s[1], nil)
|
174
|
+
end
|
175
|
+
|
168
176
|
send_data("DELETED\r\n")
|
169
177
|
end
|
170
178
|
|
@@ -208,6 +216,12 @@ module Roma
|
|
208
216
|
end
|
209
217
|
}
|
210
218
|
return send_data("NOT_FOUND\r\n") unless res[4]
|
219
|
+
|
220
|
+
if $roma.cr_writer.run_replication
|
221
|
+
fnc = 'delete'
|
222
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{s[1]}\r\n", s[1], nil)
|
223
|
+
end
|
224
|
+
|
211
225
|
send_data("DELETED\r\n")
|
212
226
|
end
|
213
227
|
|
@@ -339,6 +353,10 @@ module Roma
|
|
339
353
|
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt], key, expt.to_s)
|
340
354
|
end
|
341
355
|
redundant(nodes[1..-1], hname, key, d, ret[2], ret[3], ret[4])
|
356
|
+
if $roma.cr_writer.run_replication
|
357
|
+
fnc = 'set_expt'
|
358
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{s[1]} #{expt}\r\n", s[1], expt)
|
359
|
+
end
|
342
360
|
send_data("STORED\r\n")
|
343
361
|
else
|
344
362
|
return send_data("NOT_STORED\r\n")
|
@@ -376,12 +394,69 @@ module Roma
|
|
376
394
|
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt], key, expt.to_s)
|
377
395
|
end
|
378
396
|
redundant(nodes[1..-1], hname, key, d, ret[2], ret[3], ret[4])
|
397
|
+
if $roma.cr_writer.run_replication
|
398
|
+
fnc = 'set_expt'
|
399
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{s[1]} #{expt}\r\n", s[1], expt)
|
400
|
+
end
|
379
401
|
send_data("STORED\r\n")
|
380
402
|
else
|
381
403
|
return send_data("NOT_STORED\r\n")
|
382
404
|
end
|
383
405
|
end
|
384
406
|
|
407
|
+
# If you want to get expired time as UNIXTIME, set the 'unix' in last argument
|
408
|
+
# Unless set this, expired time will be sent back as date format.
|
409
|
+
# get_expt <key> [unix]
|
410
|
+
def ev_get_expt(s)
|
411
|
+
unless s.length.between?(2, 3)
|
412
|
+
@log.error("get_expt: wrong number of arguments(#{s.length-1} to 2-3)")
|
413
|
+
return send_data("CLIENT_ERROR Wrong number of arguments.\r\n")
|
414
|
+
end
|
415
|
+
case s[2]
|
416
|
+
when 'unix'
|
417
|
+
is_unix = true
|
418
|
+
when nil
|
419
|
+
is_unix = false
|
420
|
+
else
|
421
|
+
@log.error("get_expt: wrong format of arguments.")
|
422
|
+
return send_data("CLIENT_ERROR Wrong format of arguments.\r\n")
|
423
|
+
end
|
424
|
+
|
425
|
+
key, hname = s[1].split("\e")
|
426
|
+
hname ||= @defhash
|
427
|
+
unless @storages.key?(hname)
|
428
|
+
send_data("SERVER_ERROR #{hname} does not exists.\r\n")
|
429
|
+
return
|
430
|
+
end
|
431
|
+
|
432
|
+
d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
|
433
|
+
vn = @rttable.get_vnode_id(d)
|
434
|
+
|
435
|
+
nodes = @rttable.search_nodes(vn)
|
436
|
+
unless nodes.include?(@nid)
|
437
|
+
@log.warn("forward get_expt #{s[1]} #{s[2]}")
|
438
|
+
res = forward_get_expt(nodes[0], vn, s[1], s[2])
|
439
|
+
if res
|
440
|
+
send_data(res)
|
441
|
+
else
|
442
|
+
send_data("SERVER_ERROR Message forward failed.\r\n")
|
443
|
+
end
|
444
|
+
return
|
445
|
+
end
|
446
|
+
|
447
|
+
data = @storages[hname].db_get(vn, key)
|
448
|
+
if data
|
449
|
+
if is_unix
|
450
|
+
expt = data.unpack('NNNNa*')[3]
|
451
|
+
else
|
452
|
+
expt = Time.at(data.unpack('NNNNa*')[3])
|
453
|
+
end
|
454
|
+
send_data("#{expt}\r\n")
|
455
|
+
end
|
456
|
+
send_data("END\r\n")
|
457
|
+
end
|
458
|
+
|
459
|
+
|
385
460
|
# set_size_of_zredundant <n>
|
386
461
|
def ev_set_size_of_zredundant(s)
|
387
462
|
if s.length != 2 || s[1].to_i == 0
|
@@ -451,6 +526,22 @@ module Roma
|
|
451
526
|
nil
|
452
527
|
end
|
453
528
|
|
529
|
+
def forward_get_expt(nid, vn, key, is_unix=nil)
|
530
|
+
con = get_connection(nid)
|
531
|
+
con.send("get_expt #{key} #{is_unix}\r\n")
|
532
|
+
res = ''
|
533
|
+
while((line = con.gets)!="END\r\n")
|
534
|
+
res = line.chomp
|
535
|
+
end
|
536
|
+
return_connection(nid, con)
|
537
|
+
@rttable.proc_succeed(nid)
|
538
|
+
res
|
539
|
+
rescue => e
|
540
|
+
@rttable.proc_failed(nid)
|
541
|
+
@log.error("forward get_expt failed:nid=#{nid} key=#{key}")
|
542
|
+
nil
|
543
|
+
end
|
544
|
+
|
454
545
|
def store(fnc, hname, vn, k, d, expt, v, nodes)
|
455
546
|
expt = chg_time_expt(expt)
|
456
547
|
unless @storages.key?(hname)
|
@@ -471,6 +562,10 @@ module Roma
|
|
471
562
|
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[fnc], k, ret[4])
|
472
563
|
end
|
473
564
|
redundant(nodes, hname, k, d, ret[2], expt, ret[4])
|
565
|
+
if $roma.cr_writer.run_replication
|
566
|
+
k = "#{k}\e#{hname}" if hname != @defhash
|
567
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{k} 1 #{expt} #{v.length} \r\n#{v}\r\n", k, v)
|
568
|
+
end
|
474
569
|
send_data("STORED\r\n")
|
475
570
|
else
|
476
571
|
@log.error("#{fnc} NOT_STORED:#{hname} #{vn} #{k} #{d} #{expt}")
|
@@ -505,6 +600,11 @@ module Roma
|
|
505
600
|
if @stats.wb_command_map.key?(:cas)
|
506
601
|
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:cas], k, ret[4])
|
507
602
|
end
|
603
|
+
if $roma.cr_writer.run_replication
|
604
|
+
k = "#{k}\e#{hname}" if hname != @defhash
|
605
|
+
fnc = 'set' # To restrain a defference between main and replica cluster due to clk
|
606
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{k} 0 #{expt} #{v.length} \r\n#{v}\r\n", k, v)
|
607
|
+
end
|
508
608
|
redundant(nodes, hname, k, d, ret[2], expt, ret[4])
|
509
609
|
send_data("STORED\r\n")
|
510
610
|
end
|
@@ -585,7 +685,7 @@ module Roma
|
|
585
685
|
store(fnc, hname, vn, key, d, s[3].to_i, v, nodes)
|
586
686
|
end
|
587
687
|
|
588
|
-
def store_incr_decr(fnc, hname, vn, k, d,
|
688
|
+
def store_incr_decr(fnc, hname, vn, k, d, v, nodes)
|
589
689
|
unless @storages.key?(hname)
|
590
690
|
send_data("SERVER_ERROR #{hname} does not exists.\r\n")
|
591
691
|
return
|
@@ -603,6 +703,10 @@ module Roma
|
|
603
703
|
if @stats.wb_command_map.key?(fnc)
|
604
704
|
Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[fnc], k, res[4])
|
605
705
|
end
|
706
|
+
if $roma.cr_writer.run_replication
|
707
|
+
k = "#{k}\e#{hname}" if hname != @defhash
|
708
|
+
Roma::WriteBehindProcess::push(nil, "#{fnc} #{k} #{v}\r\n", k, v)
|
709
|
+
end
|
606
710
|
redundant(nodes, hname, k, d, res[2], res[3], res[4])
|
607
711
|
send_data("#{res[4]}\r\n")
|
608
712
|
else
|