roma 0.8.13 → 0.8.14

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.
@@ -21,8 +21,6 @@ module Roma
21
21
  def incr(vn, k, d, v); end
22
22
  def decr(vn, k, d, v); end
23
23
  def true_length; 100; end
24
- def add_vnode(vn); end
25
- def del_vnode(vn); end
26
24
  def clean_up(t); end
27
25
 
28
26
  def load(dmp); 10 end
@@ -8,15 +8,18 @@ module Roma
8
8
  def get(k); self[k]; end
9
9
  def out(k); delete(k); end
10
10
  def rnum; length; end
11
+ def sync; true; end
11
12
  end
12
13
 
13
14
  class RubyHashStorage < BasicStorage
14
15
 
15
16
  def opendb
16
17
  create_div_hash
17
- @divnum.times{ |i|
18
+ @divnum.times do |i|
18
19
  @hdb[i] = open_db(nil)
19
- }
20
+ @hdbc[i] = nil
21
+ @dbs[i] = :normal
22
+ end
20
23
  end
21
24
 
22
25
  if RUBY_VERSION >= '1.9.2'
@@ -42,25 +45,23 @@ module Roma
42
45
  }
43
46
  end
44
47
 
45
- def each_vn_dump(target_vn)
48
+ def each_unpacked_db(target_vn, db)
46
49
  count = 0
47
50
  tn = Time.now.to_i
48
- keys = @hdb[@hdiv[target_vn]].keys
49
- keys.each{|k|
50
- v = @hdb[@hdiv[target_vn]][k]
51
+ keys = db[@hdiv[target_vn]].keys
52
+ keys.each do |k|
53
+ v = db[@hdiv[target_vn]][k]
51
54
  vn, last, clk, expt, val = unpack_data(v)
52
55
  if vn != target_vn || (expt != 0 && tn > expt)
53
56
  count += 1
54
57
  sleep @each_vn_dump_sleep if count % @each_vn_dump_sleep_count == 0
55
58
  next
56
59
  end
57
- if val
58
- yield [vn, last, clk, expt, k.length, k, val.length, val].pack("NNNNNa#{k.length}Na#{val.length}")
59
- else
60
- yield [vn, last, clk, expt, k.length, k, 0].pack("NNNNNa#{k.length}N")
61
- end
62
- }
60
+ yield vn, last, clk, expt, k, val
61
+ end
63
62
  end
63
+ private :each_unpacked_db
64
+
64
65
 
65
66
  def each_hdb_dump(i,except_vnh = nil)
66
67
  count = 0
@@ -56,6 +56,10 @@ module Roma
56
56
  "WHERE type='table' ORDER BY name;"
57
57
  self.execute( sql ).flatten
58
58
  end
59
+
60
+ def sync
61
+ true
62
+ end
59
63
  end
60
64
 
61
65
  class SQLite3Storage < BasicStorage
@@ -32,7 +32,7 @@ module Roma
32
32
  end
33
33
  ret
34
34
  end
35
- end
35
+ end # class TokyoCabinet::HDB
36
36
 
37
37
  def initialize
38
38
  super
@@ -51,33 +51,18 @@ module Roma
51
51
  end
52
52
 
53
53
  def opendb
54
- create_div_hash
55
- path = ''
56
- @storage_path.split('/').each{|p|
57
- if p.length==0
58
- path = '/'
59
- next
60
- end
61
- path << p
62
- Dir::mkdir(path) unless File.exist?(path)
63
- path << '/'
64
- }
65
-
66
54
  @fname_lock = "#{@storage_path}/lock"
67
55
  if File.exist?(@fname_lock)
68
56
  raise RuntimeError.new("Lock file already exists.")
69
57
  end
70
- open(@fname_lock,"w"){}
71
58
 
72
- @divnum.times{ |i|
73
- @hdb[i] = open_db("#{@storage_path}/#{i}.#{@ext_name}")
74
- }
59
+ super
60
+
61
+ open(@fname_lock,"w"){}
75
62
  end
76
63
 
77
64
  def closedb
78
- stop_clean_up
79
- buf = @hdb; @hdb = []
80
- buf.each{ |hdb| close_db(hdb) }
65
+ super
81
66
 
82
67
  File.unlink(@fname_lock) if @fname_lock
83
68
  @fname_lock = nil
@@ -202,6 +187,7 @@ module Roma
202
187
  opts += "#bnum=#{prop['bnum']}" if prop.key?('bnum')
203
188
  opts += "#capnum=#{prop['capnum']}" if prop.key?('capnum')
204
189
  opts += "#capsiz=#{prop['capsiz']}" if prop.key?('capsiz')
190
+
205
191
  opts = nil unless opts.length > 0
206
192
  opts
207
193
  end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'socket'
4
+
5
+ module Roma
6
+ class SafeCopy
7
+
8
+ attr_reader :storages
9
+
10
+ def initialize(addr, port)
11
+ @con = TCPSocket.open(addr, port)
12
+ get_storage_info
13
+ end
14
+
15
+ def backup_all
16
+ @storages.keys.each do |k|
17
+ backup(k)
18
+ end
19
+ end
20
+
21
+ def backup(hname)
22
+ stat = get_safecopy_stats(hname)
23
+ if stat.uniq != [:normal]
24
+ puts "storages[#{hname}].storage.safecopy_stats #{stat.to_s}"
25
+ puts "ERROR: Status except the :normal exists."
26
+ return
27
+ end
28
+ @storages[hname].each_with_index do |fname, num|
29
+ ret = set_storage_status(hname, num, "safecopy")
30
+ if ret != "PUSHED\r\n"
31
+ puts ret
32
+ puts "ERROR: Can't change storage status to safecopy."
33
+ return
34
+ end
35
+ wait(hname, num, :safecopy_flushed)
36
+ puts "copy file : #{fname}"
37
+ # file copy
38
+ `cp #{fname} #{fname}.#{Time.now.strftime("%Y%m%d%H%M%S")}`
39
+ ret = set_storage_status(hname, num, "normal")
40
+ if ret != "PUSHED\r\n"
41
+ puts ret
42
+ puts "ERROR: Can't change storage status to normal."
43
+ return
44
+ end
45
+ wait(hname, num, :normal)
46
+ end
47
+ end
48
+
49
+ def wait(hname, num, stat)
50
+ print "waiting for storages[#{hname}][#{num}] == #{stat} "
51
+ while get_safecopy_stats(hname)[num] != stat
52
+ print "."
53
+ sleep 5
54
+ end
55
+ puts
56
+ end
57
+
58
+ def get_storage_info
59
+ @storages = {}
60
+ stats do |line|
61
+ if /^storages\[(.+)\]\.storage\[(\d+)\]\.path\s(.+)/ =~ line
62
+ @storages[$1] = [] unless @storages.key? $1
63
+ @storages[$1][$2.to_i] = $3.chomp
64
+ # puts "#{$1} #{$2} #{$3}"
65
+ end
66
+ end
67
+ end
68
+
69
+ def get_safecopy_stats(hname)
70
+ ret = nil
71
+ stats do |line|
72
+ if /^storages\[#{hname}\]\.storage\.safecopy_stats\s(.+)/ =~ line
73
+ ret = $1.chomp
74
+ end
75
+ end
76
+ eval ret
77
+ end
78
+
79
+ def set_storage_status(hname, num, stat)
80
+ @con.puts "set_storage_status #{num} #{stat} #{hname}\r\n"
81
+ @con.gets
82
+ end
83
+
84
+ def stats
85
+ @con.puts "stat storage\r\n"
86
+ yield $_ while @con.gets != "END\r\n"
87
+ end
88
+
89
+ def close
90
+ @con.close if @con
91
+ end
92
+
93
+ end # SafeCopy
94
+ end # Roma
95
+
96
+ if ARGV.length < 1
97
+ puts File.basename(__FILE__) + " [port]"
98
+ exit
99
+ end
100
+
101
+ sc = Roma::SafeCopy.new("localhost", ARGV[0].to_i)
102
+ sc.backup_all
103
+ sc.close
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'date'
4
+ require 'roma/client/rclient'
5
+
6
+ @cnt = 0
7
+ @tmax = 0
8
+ @tmin = 100
9
+
10
+ @m = Mutex.new
11
+
12
+ Thread.new do
13
+ sleep_time=10
14
+ while(true)
15
+ sleep sleep_time
16
+ printf("\s\sqps=%d max=%f min=%f ave=%f\n",@cnt/sleep_time,@tmax,@tmin,sleep_time/@cnt.to_f)
17
+ @cnt=0
18
+ @tmax=0
19
+ @tmin=100
20
+ end
21
+ end
22
+
23
+ def random_rquest_sender(ini_nodes, n)
24
+ puts __method__
25
+ rc=Roma::Client::RomaClient.new(ini_nodes)
26
+
27
+ loop do
28
+ i=rand(n)
29
+ ts = DateTime.now
30
+ case rand(3)
31
+ when 0
32
+ res=rc.set(i.to_s,'hoge'+i.to_s)
33
+ puts "set k=#{i} #{res}" if res==nil || res.chomp != 'STORED'
34
+ when 1
35
+ res=rc.get(i.to_s)
36
+ puts "get k=#{i} #{res}" if res == :error
37
+ when 2
38
+ res=rc.delete(i.to_s)
39
+ puts "del k=#{i} #{res}" if res != 'DELETED' && res != 'NOT_FOUND'
40
+ end
41
+ t=(DateTime.now - ts).to_f * 86400.0
42
+ @tmax=t if t > @tmax
43
+ @tmin=t if t < @tmin
44
+ @cnt+=1
45
+ end
46
+ end
47
+
48
+ def set_counts(ini_nodes, range, key_prefix, value)
49
+ puts "\s\s#{__method__} #{range} #{value}"
50
+ rc=Roma::Client::RomaClient.new(ini_nodes)
51
+ @range_cnt = 0
52
+
53
+ range.each do |i|
54
+ ts = DateTime.now
55
+ @range_cnt = i
56
+ res=rc.set("#{key_prefix}_#{i}","#{value}")
57
+ puts "set #{key_prefix}_#{i}=#{value} #{res}" if res==nil || res.chomp != 'STORED'
58
+ t=(DateTime.now - ts).to_f * 86400.0
59
+ @tmax=t if t > @tmax
60
+ @tmin=t if t < @tmin
61
+ @cnt+=1
62
+ end
63
+ end
64
+
65
+ def check_count(ini_nodes, range, key_prefix, value)
66
+ puts "\s\s#{__method__} #{range} #{value}"
67
+ rc=Roma::Client::RomaClient.new(ini_nodes)
68
+
69
+ range.each do |i|
70
+ ts = DateTime.now
71
+ res = rc.get("#{key_prefix}_#{i}")
72
+ if res != value.to_s
73
+ puts "error k=#{key_prefix}_#{i} #{res}"
74
+ end
75
+
76
+ t=(DateTime.now - ts).to_f * 86400.0
77
+ @tmax=t if t > @tmax
78
+ @tmin=t if t < @tmin
79
+ @cnt+=1
80
+ end
81
+ end
82
+
83
+ def send_cmd(nid, cmd)
84
+ conn = Roma::Client::ConPool.instance.get_connection(nid)
85
+ conn.write "#{cmd}\r\n"
86
+ ret = conn.gets
87
+ Roma::Client::ConPool.instance.return_connection(nid, conn)
88
+ ret
89
+ rescue =>e
90
+ STDERR.puts "#{nid} #{cmd} #{e.inspect}"
91
+ nil
92
+ end
93
+
94
+ def stats(nid, regexp=nil)
95
+ conn = Roma::Client::ConPool.instance.get_connection(nid)
96
+ if regexp
97
+ conn.write "stats #{regexp}\r\n"
98
+ else
99
+ conn.write "stats\r\n"
100
+ end
101
+ ret = ""
102
+ while(conn.gets != "END\r\n")
103
+ ret << $_
104
+ end
105
+ Roma::Client::ConPool.instance.return_connection(nid, conn)
106
+ ret
107
+ rescue =>e
108
+ STDERR.puts "#{nid} #{e.inspect}"
109
+ nil
110
+ end
111
+
112
+ def safecopy_stats(nid)
113
+ ret = stats(nid, 'storage.safecopy_stats')
114
+ return eval $1 if ret =~ /^.+\s(\[.+\])/
115
+ nil
116
+ end
117
+
118
+ def set_storage_status(nid, fno, stat)
119
+ send_cmd(ARGV[0], "set_storage_status #{fno} #{stat}")
120
+ end
121
+
122
+ def wait_status(nid, fno, stat)
123
+ while safecopy_stats(nid)[fno] != stat
124
+ sleep 5
125
+ end
126
+ stat
127
+ end
128
+
129
+ def test_change_status
130
+
131
+ puts "write (0...10000) = 0"
132
+ set_counts(ARGV, 0...10000, "default_key",0)
133
+ Thread.new { random_rquest_sender(ARGV, 10000) }
134
+
135
+ set_counts(ARGV, 0...1000, "flushing_key", 0)
136
+ set_counts(ARGV, 0...1000, "caching_key", 0)
137
+
138
+ nid = ARGV[0]
139
+
140
+ sleep(5)
141
+
142
+ 10.times do |n|
143
+ puts "\n#{n+1}th loop(#{n}.tc)****************************************************************** "
144
+
145
+ #========================================================================================
146
+ #flushing(normal => safecopy_flushed)
147
+ flush_loop_count = 0
148
+ @range_cnt = 0
149
+ @flag = false
150
+
151
+ t = Thread.new {
152
+ loop{
153
+ flush_loop_count += 1
154
+ set_counts(ARGV, 0...1000, "flushing_key", flush_loop_count)
155
+ @flag = true
156
+ }
157
+ }
158
+ while !@flag do
159
+ puts "\s\s[debug]sleep flushing start"
160
+ sleep(1)
161
+ puts "\s\s[debug]sleep flushing end"
162
+ end
163
+ puts "\s\s#{set_storage_status(nid, n, 'safecopy')}"
164
+ puts "#{wait_status(nid, n, :safecopy_flushed)}"
165
+
166
+ #sleep(5)
167
+ t.kill
168
+
169
+ flushing_range_cnt = @range_cnt
170
+ puts "\s\s#{safecopy_stats(nid)}\n\n"
171
+
172
+ #========================================================================================
173
+ #Caching(safecopy_flushed => normal)
174
+ #sleep(30)
175
+ cache_loop_count = 0
176
+ @range_cnt = 0
177
+ @flag = false
178
+ t = Thread.new {
179
+ loop{
180
+ cache_loop_count += 1
181
+ set_counts(ARGV, 0...1000, "caching_key", cache_loop_count)
182
+ @flag = true
183
+ }
184
+ }
185
+ while !@flag do
186
+ puts "\s\s[debug]sleep caching start"
187
+ sleep(1)
188
+ puts "\s\s[debug]sleep caching end"
189
+ end
190
+
191
+ puts "\s\s#{set_storage_status(nid, n, 'normal')}"
192
+ puts "#{wait_status(nid, n, :normal)}"
193
+
194
+ #sleep(5)
195
+ t.kill
196
+
197
+ caching_range_cnt = @range_cnt
198
+ puts "\s\s#{safecopy_stats(nid)}"
199
+
200
+ #========================================================================================
201
+ #check
202
+ puts "\n[Check]"
203
+ puts "\s\sflushing key"
204
+ check_count(ARGV, 0..flushing_range_cnt, "flushing_key", flush_loop_count)
205
+ check_count(ARGV, flushing_range_cnt+1...1000, "flushing_key", flush_loop_count-1)
206
+
207
+ puts "\n\s\scaching key"
208
+ check_count(ARGV, 0..caching_range_cnt, "caching_key", cache_loop_count)
209
+ check_count(ARGV, caching_range_cnt+1...1000, "caching_key", cache_loop_count-1) if cache_loop_count != 1
210
+ end
211
+ end
212
+
213
+ def test_round
214
+ n = 0
215
+ 1000.times do |i|
216
+ set_counts(ARGV, 0...10000, i)
217
+ check_count(ARGV, 0...10000, i)
218
+ end
219
+ end
220
+
221
+ param = { :num=>10000, :th=>1 }
222
+
223
+ opts = OptionParser.new
224
+
225
+ opts.on("-r", "--round", "round request"){|v| param[:round] = v }
226
+ opts.on("-c", "--count [x]", "counts of the test times"){|v| param[:count] = v.to_i }
227
+
228
+ opts.banner = "usage:#{File.basename($0)} [options] addr:port"
229
+ opts.parse!(ARGV)
230
+
231
+ if ARGV.length == 0
232
+ STDERR.puts opts.help
233
+ exit
234
+ end
235
+
236
+ if param.key?(:round)
237
+ test_round
238
+ else
239
+ param[:count] = 1 if !param.key?(:count)
240
+
241
+ param[:count].times do |count|
242
+ puts "#{count+1}th test========================================================================================="
243
+ test_change_status
244
+ end
245
+ end
246
+
247
+ puts "#{File.basename($0)} has done."