roma 0.8.2 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/CHANG +326 -0
  2. data/CHANGELOG +132 -0
  3. data/{README.rdoc → FETCH_HEAD} +0 -0
  4. data/{LICENSE.rdoc → LICENSE} +0 -1
  5. data/README +17 -0
  6. data/Rakefile +33 -18
  7. data/ruby/server/bin/chg_redundancy +10 -0
  8. data/ruby/server/bin/key_access +7 -0
  9. data/ruby/server/bin/key_list +7 -0
  10. data/ruby/server/bin/mkconfig +19 -0
  11. data/{bin → ruby/server/bin}/mkrecent +0 -1
  12. data/{bin → ruby/server/bin}/mkroute +0 -1
  13. data/ruby/server/bin/multi_commander +19 -0
  14. data/ruby/server/bin/recoverlost +10 -0
  15. data/ruby/server/bin/recoverlost_alist +10 -0
  16. data/ruby/server/bin/recoverlost_alist_all +10 -0
  17. data/ruby/server/bin/recoverlost_alist_keys +10 -0
  18. data/{bin/recoverlost → ruby/server/bin/roma_watcher} +1 -2
  19. data/ruby/server/bin/romad +36 -0
  20. data/{bin → ruby/server/bin}/sample_watcher +0 -1
  21. data/{bin → ruby/server/bin}/sample_watcher2 +0 -1
  22. data/{bin/simple_bench → ruby/server/bin/sample_watcher3} +1 -2
  23. data/ruby/server/bin/simple_bench +26 -0
  24. data/{bin → ruby/server/bin}/ssroute +0 -1
  25. data/ruby/server/bin/test-scenario +11 -0
  26. data/{bin → ruby/server/bin}/tribunus +0 -1
  27. data/{lib → ruby/server/lib}/roma/async_process.rb +67 -15
  28. data/{lib → ruby/server/lib}/roma/command/bg_command_receiver.rb +1 -1
  29. data/ruby/server/lib/roma/command/command_definition.rb +422 -0
  30. data/ruby/server/lib/roma/command/mh_command_receiver.rb +127 -0
  31. data/ruby/server/lib/roma/command/receiver.rb +64 -0
  32. data/{lib → ruby/server/lib}/roma/command/rt_command_receiver.rb +6 -1
  33. data/ruby/server/lib/roma/command/sys_command_receiver.rb +609 -0
  34. data/{lib → ruby/server/lib}/roma/command/util_command_receiver.rb +15 -5
  35. data/{lib → ruby/server/lib}/roma/command/vn_command_receiver.rb +12 -4
  36. data/{lib → ruby/server/lib}/roma/command_plugin.rb +0 -0
  37. data/ruby/server/lib/roma/config.rb +84 -0
  38. data/{lib → ruby/server/lib}/roma/event/con_pool.rb +12 -1
  39. data/ruby/server/lib/roma/event/handler.rb +256 -0
  40. data/ruby/server/lib/roma/live_patch-20120302-001.rb +107 -0
  41. data/ruby/server/lib/roma/logging/rlogger.rb +163 -0
  42. data/ruby/server/lib/roma/messaging/con_pool.rb +92 -0
  43. data/{lib → ruby/server/lib}/roma/plugin/plugin_alist.rb +118 -240
  44. data/ruby/server/lib/roma/plugin/plugin_debug.rb +31 -0
  45. data/ruby/server/lib/roma/plugin/plugin_map.rb +177 -0
  46. data/ruby/server/lib/roma/plugin/plugin_mapcount.rb +185 -0
  47. data/{lib/roma/command/st_command_receiver.rb → ruby/server/lib/roma/plugin/plugin_storage.rb} +170 -146
  48. data/ruby/server/lib/roma/plugin/plugin_stub.rb +283 -0
  49. data/{lib → ruby/server/lib}/roma/plugin/plugin_test.rb +0 -0
  50. data/{lib → ruby/server/lib}/roma/romad.rb +221 -94
  51. data/{lib → ruby/server/lib}/roma/routing/cb_rttable.rb +4 -6
  52. data/{lib → ruby/server/lib}/roma/routing/merkle_tree.rb +0 -0
  53. data/ruby/server/lib/roma/routing/routing_data.rb +307 -0
  54. data/{lib → ruby/server/lib}/roma/routing/rttable.rb +4 -0
  55. data/{lib → ruby/server/lib}/roma/stats.rb +19 -3
  56. data/{lib → ruby/server/lib}/roma/storage/basic_storage.rb +25 -26
  57. data/{lib → ruby/server/lib}/roma/storage/dbm_storage.rb +1 -23
  58. data/{lib → ruby/server/lib}/roma/storage/dummy_storage.rb +0 -0
  59. data/{lib → ruby/server/lib}/roma/storage/rh_storage.rb +0 -0
  60. data/{lib → ruby/server/lib}/roma/storage/sqlite3_storage.rb +0 -0
  61. data/{lib → ruby/server/lib}/roma/storage/tc_storage.rb +62 -2
  62. data/ruby/server/lib/roma/tools/chg_redundancy.rb +36 -0
  63. data/ruby/server/lib/roma/tools/key_access.rb +105 -0
  64. data/ruby/server/lib/roma/tools/key_list.rb +94 -0
  65. data/ruby/server/lib/roma/tools/mkconfig.rb +535 -0
  66. data/{lib → ruby/server/lib}/roma/tools/mkrecent.rb +0 -0
  67. data/{lib → ruby/server/lib}/roma/tools/mkroute.rb +0 -0
  68. data/ruby/server/lib/roma/tools/multi_commander.rb +45 -0
  69. data/{lib → ruby/server/lib}/roma/tools/recoverlost.rb +0 -0
  70. data/{lib → ruby/server/lib}/roma/tools/recoverlost_alist.rb +0 -0
  71. data/ruby/server/lib/roma/tools/recoverlost_alist_all.rb +8 -0
  72. data/ruby/server/lib/roma/tools/recoverlost_alist_keys.rb +16 -0
  73. data/ruby/server/lib/roma/tools/recoverlost_lib.rb +349 -0
  74. data/ruby/server/lib/roma/tools/roma_watcher.rb +150 -0
  75. data/ruby/server/lib/roma/tools/roma_watcher_config.yml.example +20 -0
  76. data/{lib → ruby/server/lib}/roma/tools/sample_watcher.rb +3 -1
  77. data/{lib → ruby/server/lib}/roma/tools/sample_watcher2.rb +3 -1
  78. data/ruby/server/lib/roma/tools/sample_watcher3.rb +49 -0
  79. data/{lib → ruby/server/lib}/roma/tools/simple_bench.rb +2 -0
  80. data/ruby/server/lib/roma/tools/simple_bench2.rb +78 -0
  81. data/{lib → ruby/server/lib}/roma/tools/ssroute.rb +0 -0
  82. data/ruby/server/lib/roma/tools/test-scenario.rb +327 -0
  83. data/{lib → ruby/server/lib}/roma/tools/tribunus.rb +0 -0
  84. data/ruby/server/lib/roma/version.rb +4 -0
  85. data/{lib → ruby/server/lib}/roma/write_behind.rb +1 -0
  86. data/ruby/server/test/config4mhash.rb +68 -0
  87. data/ruby/server/test/config4storage_error.rb +69 -0
  88. data/{lib/roma/config.rb → ruby/server/test/config4test.rb} +6 -3
  89. data/{test → ruby/server/test}/rcirb.rb +0 -1
  90. data/{test → ruby/server/test}/roma-test-utils.rb +21 -8
  91. data/{test → ruby/server/test}/run-test.rb +3 -2
  92. data/ruby/server/test/storage_error_storage.rb +37 -0
  93. data/ruby/server/test/t_command_definition.rb +326 -0
  94. data/{test → ruby/server/test}/t_cpdata.rb +9 -3
  95. data/{test → ruby/server/test}/t_listplugin.rb +48 -12
  96. data/ruby/server/test/t_mapcountplugin.rb +231 -0
  97. data/ruby/server/test/t_mapplugin.rb +131 -0
  98. data/ruby/server/test/t_mhash.rb +222 -0
  99. data/ruby/server/test/t_rclient.rb +199 -0
  100. data/{test → ruby/server/test}/t_routing_data.rb +56 -0
  101. data/{test → ruby/server/test}/t_storage.rb +107 -111
  102. data/ruby/server/test/t_storage_error.rb +61 -0
  103. data/ruby/server/test/t_writebehind.rb +374 -0
  104. metadata +150 -82
  105. data/bin/recoverlost_alist +0 -8
  106. data/bin/romad +0 -7
  107. data/lib/roma/command/mh_command_receiver.rb +0 -117
  108. data/lib/roma/command/receiver.rb +0 -287
  109. data/lib/roma/event/handler.rb +0 -159
  110. data/lib/roma/plugin/plugin_debug.rb +0 -19
  111. data/lib/roma/tools/recoverlost_lib.rb +0 -217
  112. data/lib/roma/version.rb +0 -4
  113. data/test/t_rclient.rb +0 -318
  114. data/test/t_writebehind.rb +0 -200
@@ -0,0 +1,31 @@
1
+
2
+ module Roma
3
+ module CommandPlugin
4
+
5
+ module PluginOperation
6
+ include ::Roma::CommandPlugin
7
+
8
+ # DANGER!!
9
+ def ev_eval(s)
10
+ cmd = s[1..-1].join(' ')
11
+ @log.debug("eval(#{cmd})")
12
+ send_data("#{eval(cmd)}\r\n")
13
+ rescue Exception =>e
14
+ send_data("#{e}\r\n")
15
+ end
16
+
17
+ def get_key_info(key)
18
+ d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
19
+ vn = @rttable.get_vnode_id(d)
20
+ nodes = @rttable.search_nodes_for_write(vn)
21
+ s = sprintf("d = %s 0x%x\r\n",d,d)
22
+ send_data(s)
23
+ s = sprintf("vn = %s 0x%x\r\n",vn,vn)
24
+ send_data(s)
25
+ send_data("nodes = #{nodes.inspect}\r\n")
26
+ "END"
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,177 @@
1
+ require 'roma/messaging/con_pool'
2
+ require 'roma/command/command_definition'
3
+
4
+ module Roma
5
+ module CommandPlugin
6
+
7
+ module PluginMap
8
+ include Roma::CommandPlugin
9
+ include Roma::Command::Definition
10
+
11
+ # map_set <key> <mapkey> <flags> <expt> <bytes> [forward]\r\n
12
+ # <data block>\r\n
13
+ #
14
+ # (STORED|NOT_STORED|SERVER_ERROR <error message>)\r\n
15
+ def_write_command_with_key_value :map_set, 5 do |ctx|
16
+ v = {}
17
+ v = Marshal.load(ctx.stored.value) if ctx.stored
18
+
19
+ v[ctx.argv[2]] = ctx.params.value
20
+ expt = chg_time_expt(ctx.argv[4].to_i)
21
+
22
+ # [flags, expire time, value, kind of counter(:write/:delete), result message]
23
+ [0, expt, Marshal.dump(v), :write, 'STORED']
24
+ end
25
+
26
+ # map_get <key> <mapkey> [forward]\r\n
27
+ #
28
+ # (
29
+ # [VALUE <key> 0 <value length>\r\n
30
+ # <value>\r\n]
31
+ # END\r\n
32
+ # |SERVER_ERROR <error message>\r\n)
33
+ def_read_command_with_key :map_get, :multi_line do |ctx|
34
+ if ctx.stored
35
+ v = Marshal.load(ctx.stored.value)[ctx.argv[2]]
36
+ send_data("VALUE #{ctx.params.key} 0 #{v.length}\r\n#{v}\r\n") if v
37
+ end
38
+ send_data("END\r\n")
39
+ end
40
+
41
+ # map_delete <key> <mapkey> [forward]\r\n
42
+ #
43
+ # (DELETED|NOT_DELETED|NOT_FOUND|SERVER_ERROR <error message>)\r\n
44
+ def_write_command_with_key :map_delete do |ctx|
45
+ next send_data("NOT_FOUND\r\n") unless ctx.stored
46
+
47
+ v = Marshal.load(ctx.stored.value)
48
+ next send_data("NOT_DELETED\r\n") unless v.key?(ctx.argv[2])
49
+
50
+ v.delete(ctx.argv[2])
51
+
52
+ [0, ctx.stored.expt, Marshal.dump(v), :delete, 'DELETED']
53
+ end
54
+
55
+ # map_clear <key> [forward]\r\n
56
+ #
57
+ # (CLEARED|NOT_CLEARED|NOT_FOUND|SERVER_ERROR <error message>)\r\n
58
+ def_write_command_with_key :map_clear do |ctx|
59
+ next send_data("NOT_FOUND\r\n") unless ctx.stored
60
+
61
+ [0, ctx.stored.expt, Marshal.dump({}), :delete, 'CLEARED']
62
+ end
63
+
64
+
65
+ # map_size <key> [forward]\r\n
66
+ #
67
+ # (<length>|NOT_FOUND|SERVER_ERROR <error message>)\r\n
68
+ def_read_command_with_key :map_size do |ctx|
69
+ if ctx.stored
70
+ ret = Marshal.load(ctx.stored.value).size
71
+ send_data("#{ret}\r\n")
72
+ else
73
+ send_data("NOT_FOUND\r\n")
74
+ end
75
+ end
76
+
77
+ # map_key? <key> <mapkey> [forward]\r\n
78
+ #
79
+ # (true|false|NOT_FOUND|SERVER_ERROR <error message>)\r\n
80
+ def_read_command_with_key :map_key? do |ctx|
81
+ if ctx.stored
82
+ ret = Marshal.load(ctx.stored.value).key? ctx.argv[2]
83
+ send_data("#{ret}\r\n")
84
+ else
85
+ send_data("NOT_FOUND\r\n")
86
+ end
87
+ end
88
+
89
+ # map_value? <key> <bytes> [forward]\r\n
90
+ # <data block>\r\n
91
+ #
92
+ # (true|false|NOT_FOUND|SERVER_ERROR <error message>)\r\n
93
+ def_read_command_with_key_value :map_value?, 2 do |ctx|
94
+ if ctx.stored
95
+ ret = Marshal.load(ctx.stored.value).value? ctx.params.value
96
+ send_data("#{ret}\r\n")
97
+ else
98
+ send_data("NOT_FOUND\r\n")
99
+ end
100
+ end
101
+
102
+ # map_empty? <key> [forward]\r\n
103
+ #
104
+ # (true|false|NOT_FOUND|SERVER_ERROR <error message>)\r\n
105
+ def_read_command_with_key :map_empty? do |ctx|
106
+ if ctx.stored
107
+ v = Marshal.load(ctx.stored.value)
108
+ send_data("#{v.empty?}\r\n")
109
+ else
110
+ send_data("NOT_FOUND\r\n")
111
+ end
112
+ end
113
+
114
+ # map_keys <key> [forward]\r\n
115
+ #
116
+ # (
117
+ # [VALUE <key> 0 <length of length string>\r\n
118
+ # <length string>\r\n
119
+ # (VALUE <key> 0 <value length>\r\n
120
+ # <value>\r\n)*
121
+ # ]
122
+ # END\r\n
123
+ # |SERVER_ERROR <error message>\r\n)
124
+ def_read_command_with_key :map_keys, :multi_line do |ctx|
125
+ if ctx.stored
126
+ v = Marshal.load(ctx.stored.value).keys
127
+ len = v.length
128
+ send_data("VALUE #{ctx.params.key} 0 #{len.to_s.length}\r\n#{len.to_s}\r\n")
129
+ v.each{|val|
130
+ send_data("VALUE #{ctx.params.key} 0 #{val.length}\r\n#{val}\r\n")
131
+ }
132
+ end
133
+ send_data("END\r\n")
134
+ end
135
+
136
+ # map_values <key> [forward]\r\n
137
+ #
138
+ # (
139
+ # [VALUE <key> 0 <length of length string>\r\n
140
+ # <length string>\r\n
141
+ # (VALUE <key> 0 <value length>\r\n
142
+ # <value>\r\n)*
143
+ # ]
144
+ # END\r\n
145
+ # |SERVER_ERROR <error message>\r\n)
146
+ def_read_command_with_key :map_values, :multi_line do |ctx|
147
+ if ctx.stored
148
+ v = Marshal.load(ctx.stored.value).values
149
+ len = v.length
150
+ send_data("VALUE #{ctx.params.key} 0 #{len.to_s.length}\r\n#{len.to_s}\r\n")
151
+ v.each{|val|
152
+ send_data("VALUE #{ctx.params.key} 0 #{val.length}\r\n#{val}\r\n")
153
+ }
154
+ end
155
+ send_data("END\r\n")
156
+ end
157
+
158
+ # map_to_s <key> [forward]\r\n
159
+ #
160
+ # (
161
+ # [VALUE <key> 0 <value length>\r\n
162
+ # <value>\r\n]
163
+ # END\r\n
164
+ # |SERVER_ERROR <error message>\r\n)
165
+ def_read_command_with_key :map_to_s, :multi_line do |ctx|
166
+ if ctx.stored
167
+ v = Marshal.load(ctx.stored.value).inspect
168
+ send_data("VALUE #{ctx.params.key} 0 #{v.length}\r\n#{v}\r\n")
169
+ end
170
+ send_data("END\r\n")
171
+ end
172
+
173
+ end # module PluginMap
174
+ end # module CommandPlugin
175
+ end # module Roma
176
+
177
+
@@ -0,0 +1,185 @@
1
+ require 'json'
2
+ require 'roma/command/command_definition'
3
+
4
+ module Roma
5
+ module CommandPlugin
6
+
7
+ module PluginMapCount
8
+ include ::Roma::CommandPlugin
9
+ include ::Roma::Command::Definition
10
+
11
+ # mapcount_countup <key> <expt> <sub_keys_length>\r\n
12
+ # <sub_keys> \r\n
13
+ #
14
+ # (
15
+ # VALUE <key> 0 <length of json string>\r\n
16
+ # <json string>\r\n
17
+ # END\r\n
18
+ # |CLIENT_ERROR invalid sub_keys format: <sub_keys>\r\n
19
+ # |SERVER_ERROR <error message>\r\n)
20
+ def_write_command_with_key_value :mapcount_countup, 3, :multi_line do |ctx|
21
+ countup(ctx, :json)
22
+ end
23
+
24
+ # mapcount_countup_ms <key> <expt> <sub_keys_length>\r\n
25
+ # <sub_keys> \r\n
26
+ #
27
+ # (
28
+ # VALUE <key> 0 <length of Marshal string>\r\n
29
+ # <Marshal string>\r\n
30
+ # END\r\n
31
+ # |CLIENT_ERROR invalid sub_keys format: <sub_keys>\r\n
32
+ # |SERVER_ERROR <error message>\r\n)
33
+ def_write_command_with_key_value :mapcount_countup_ms, 3, :multi_line do |ctx|
34
+ countup(ctx, :marshal)
35
+ end
36
+
37
+ # mapcount_update <key> <expt> <sub_keys_length>\r\n
38
+ # <sub_keys>\r\n
39
+ #
40
+ # (
41
+ # [VALUE <key> 0 <length of json string>\r\n
42
+ # <json string>\r\n]
43
+ # END\r\n
44
+ # |SERVER_ERROR <error message>\r\n)
45
+ def_write_command_with_key_value :mapcount_update, 3, :multi_line do |ctx|
46
+ update(ctx, :json)
47
+ end
48
+
49
+ # mapcount_update_ms <key> <expt> <sub_keys_length>\r\n
50
+ # <sub_keys>\r\n
51
+ #
52
+ # (
53
+ # [VALUE <key> 0 <length of Marshal string>\r\n
54
+ # <Marshal string>\r\n]
55
+ # END\r\n
56
+ # |SERVER_ERROR <error message>\r\n)
57
+ def_write_command_with_key_value :mapcount_update_ms, 3, :multi_line do |ctx|
58
+ update(ctx, :marshal)
59
+ end
60
+
61
+ # mapcount_get <key> 0 <sub_keys_str_len>\r\n
62
+ # <sub_keys>\r\n
63
+ #
64
+ # (
65
+ # [VALUE <key> 0 <length of json string>\r\n
66
+ # <json string>\r\n]
67
+ # END\r\n
68
+ # |SERVER_ERROR <error message>\r\n)
69
+ def_read_command_with_key_value :mapcount_get, 3, :multi_line do |ctx|
70
+ get(ctx, :json)
71
+ end
72
+
73
+ # mapcount_get_ms <key> 0 <sub_keys_str_len>\r\n
74
+ # <sub_keys>\r\n
75
+ #
76
+ # (
77
+ # [VALUE <key> 0 <length of Marshal string>\r\n
78
+ # <Marshal string>\r\n]
79
+ # END\r\n
80
+ # |SERVER_ERROR <error message>\r\n)
81
+ def_read_command_with_key_value :mapcount_get_ms, 3, :multi_line do |ctx|
82
+ get(ctx, :marshal)
83
+ end
84
+
85
+ private
86
+ def countup(ctx, stype)
87
+ v = {}
88
+ v = data_load(ctx.stored.value) if ctx.stored
89
+
90
+ args = ctx.params.value.split(/\s*,\s*/)
91
+ args.each do |arg|
92
+ if arg =~ /^([A-Za-z0-9]+)(:(\-?[\d]+))?$/
93
+ key = $1
94
+ count = 1
95
+ count = $3.to_i if $3
96
+ v[key] ||= 0
97
+ v[key] += count
98
+ else
99
+ raise ClientErrorException, "invalid sub_keys format: #{ctx.params.value}"
100
+ end
101
+ end
102
+
103
+ v["last_updated_date"] = Time.now.gmtime.strftime(DATE_FORMAT)
104
+ expt = chg_time_expt(ctx.argv[2].to_i)
105
+
106
+ ret_str = return_str(v, stype)
107
+ ret_msg = "VALUE #{ctx.params.key} 0 #{ret_str.length}\r\n#{ret_str}\r\nEND"
108
+ [0, expt, Marshal.dump(v), :write, ret_msg]
109
+ end
110
+
111
+ def update(ctx, stype)
112
+ if !ctx.stored
113
+ send_data("END\r\n")
114
+ return
115
+ end
116
+
117
+ v = {}
118
+ v = data_load(ctx.stored.value)
119
+ v["last_updated_date"] = Time.now.gmtime.strftime(DATE_FORMAT)
120
+
121
+ if v.is_a?(Hash)
122
+ args = ctx.params.value.split(/\s*,\s*/)
123
+ if args.count == 0
124
+ ret = return_str(v, stype)
125
+ else
126
+ ret = {}
127
+ ret["last_updated_date"] = v["last_updated_date"]
128
+ args.each do |arg|
129
+ ret[arg] = v[arg] if v[arg] != nil
130
+ end
131
+ ret = return_str(ret, stype)
132
+ end
133
+ end
134
+
135
+ expt = chg_time_expt(ctx.argv[2].to_i)
136
+
137
+ ret_msg = "VALUE #{ctx.params.key} 0 #{ret.length}\r\n#{ret}\r\nEND"
138
+ [0, expt, Marshal.dump(v), :write, ret_msg]
139
+ end
140
+
141
+ def get(ctx, stype)
142
+ ret = nil
143
+ if ctx.stored
144
+ ret_val = data_load(ctx.stored.value)
145
+
146
+ if ret_val.is_a?(Hash)
147
+ args = ctx.params.value.split(/\s*,\s*/)
148
+ if args.count == 0
149
+ ret = return_str(ret_val, stype)
150
+ else
151
+ ret = {}
152
+ ret["last_updated_date"] = ret_val["last_updated_date"]
153
+ args.each do |arg|
154
+ ret[arg] = ret_val[arg] if ret_val[arg] != nil
155
+ end
156
+ ret = return_str(ret, stype)
157
+ end
158
+ end
159
+ end
160
+
161
+ send_data("VALUE #{ctx.params.key} 0 #{ret.length}\r\n#{ret}\r\n") if ret
162
+ send_data("END\r\n")
163
+ end
164
+
165
+ def return_str(data, stype)
166
+ return Marshal.dump(data) if stype == :marshal
167
+ data.to_json
168
+ end
169
+
170
+ def data_load(data)
171
+ begin
172
+ Marshal.load(data)
173
+ rescue => e
174
+ msg = "SERVER_ERROR #{e} #{$@}".tr("\r\n"," ")
175
+ send_data("#{msg}\r\n")
176
+ @log.error("#{e} #{$@}")
177
+ end
178
+ end
179
+
180
+ DATE_FORMAT = "%Y-%m-%dT%H:%M:%S +00"
181
+
182
+ PLUGIN_MAPCOUNT_VERSION = "1.0.1"
183
+ end # PluginMapCount
184
+ end # CommandPlugin
185
+ end # Roma
@@ -1,12 +1,12 @@
1
1
  require 'zlib'
2
2
  require 'digest/sha1'
3
- require "roma/config"
4
3
  require 'roma/async_process'
5
4
 
6
5
  module Roma
7
- module Command
6
+ module CommandPlugin
8
7
 
9
- module StorageCommandReceiver
8
+ module PluginStorage
9
+ include ::Roma::CommandPlugin
10
10
 
11
11
  # "set" means "store this data".
12
12
  # <command name> <key> <flags> <exptime> <bytes> [noreply]\r\n
@@ -14,91 +14,58 @@ module Roma
14
14
  def ev_set(s); set(:set,s); end
15
15
  def ev_fset(s); fset(:set,s); end
16
16
 
17
- # rset <key> <hash value> <timelimit> <length>
18
- # "set" means "store this data".
19
- # <command name> <key> <digest> <exptime> <bytes> [noreply]\r\n
20
- # <data block>\r\n
21
- def ev_rset(s)
17
+ # get <key>*\r\n
18
+ def ev_get(s)
19
+ return ev_gets(s) if s.length > 2
20
+
22
21
  key,hname = s[1].split("\e")
23
22
  hname ||= @defhash
24
- d = s[2].to_i
25
- d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits if d == 0
26
- data = read_bytes(s[5].to_i)
27
- read_bytes(2)
23
+ d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
28
24
  vn = @rttable.get_vnode_id(d)
29
- unless @storages.key?(hname)
30
- send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
25
+ nodes = @rttable.search_nodes(vn)
26
+
27
+ unless nodes.include?(@nid)
28
+ @log.warn("forward get #{s[1]}")
29
+ res = forward_get(nodes[0], s[1], d)
30
+ if res
31
+ send_data(res)
32
+ else
33
+ send_data("SERVER_ERROR Message forward failed.\r\n")
34
+ end
31
35
  return
32
36
  end
33
- if @storages[hname].rset(vn, key, d, s[3].to_i, s[4].to_i, data)
34
- send_data("STORED\r\n")
35
- else
36
- @log.error("rset NOT_STORED:#{@storages[hname].error_message} #{vn} #{s[1]} #{d} #{s[3]} #{s[4]}")
37
- send_data("NOT_STORED\r\n")
38
- end
39
- @stats.redundant_count += 1
40
- end
41
37
 
42
- # <command name> <key> <digest> <exptime> <bytes> [noreply]\r\n
43
- # <compressed data block>\r\n
44
- def ev_rzset(s)
45
- key,hname = s[1].split("\e")
46
- hname ||= @defhash
47
- d = s[2].to_i
48
- d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits if d == 0
49
- zdata = read_bytes(s[5].to_i)
50
- read_bytes(2)
51
- vn = @rttable.get_vnode_id(d)
52
38
  unless @storages.key?(hname)
53
39
  send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
54
40
  return
55
41
  end
56
-
57
- data = Zlib::Inflate.inflate(zdata)
58
- if @storages[hname].rset(vn, key, d, s[3].to_i, s[4].to_i, data)
59
- send_data("STORED\r\n")
60
- else
61
- @log.error("rzset NOT_STORED:#{@storages[hname].error_message} #{vn} #{s[1]} #{d} #{s[3]} #{s[4]}")
62
- send_data("NOT_STORED\r\n")
63
- end
64
- @stats.redundant_count += 1
65
- rescue Zlib::DataError => e
66
- @log.error("rzset NOT_STORED:#{e} #{vn} #{s[1]} #{d} #{s[3]} #{s[4]}")
67
- send_data("NOT_STORED\r\n")
42
+ data = @storages[hname].get(vn, key, 0)
43
+ @stats.read_count += 1
44
+ send_data("VALUE #{s[1]} 0 #{data.length}\r\n#{data}\r\n") if data
45
+ send_data("END\r\n")
68
46
  end
69
47
 
70
- # get <key>*\r\n
71
- def ev_get(s)
72
- return ev_gets(s) if s.length > 2
73
-
48
+ # fget <key>
49
+ def ev_fget(s)
74
50
  key,hname = s[1].split("\e")
75
51
  hname ||= @defhash
76
52
  d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
77
53
  vn = @rttable.get_vnode_id(d)
54
+ nodes = @rttable.search_nodes(vn)
55
+
56
+ unless nodes.include?(@nid)
57
+ @log.error("fget failed key=#{s[1]} vn=#{vn}")
58
+ return send_data("SERVER_ERROR Routing table is inconsistent.\r\n")
59
+ end
60
+
78
61
  unless @storages.key?(hname)
79
62
  send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
80
63
  return
81
64
  end
82
65
  data = @storages[hname].get(vn, key, 0)
83
66
  @stats.read_count += 1
84
- if data
85
- return send_data("VALUE #{s[1]} 0 #{data.length}\r\n#{data}\r\nEND\r\n")
86
- end
87
-
88
- nodes = @rttable.search_nodes(vn)
89
- if nodes.include?(@nid)
90
- return send_data("END\r\n")
91
- end
92
-
93
- nodes.delete(@nid)
94
- if nodes.length != 0
95
- @log.warn("forward get #{s[1]}")
96
- res = forward_get(nodes[0], s[1], d)
97
- if res
98
- return send_data(res)
99
- end
100
- end
101
- send_data("SERVER_ERROR Message forward failed.\r\n")
67
+ send_data("VALUE #{s[1]} 0 #{data.length}\r\n#{data}\r\n") if data
68
+ send_data("END\r\n")
102
69
  end
103
70
 
104
71
  # gets <key>*\r\n
@@ -150,15 +117,15 @@ module Roma
150
117
  vn = @rttable.get_vnode_id(d)
151
118
  nodes = @rttable.search_nodes_for_write(vn)
152
119
  if nodes[0] != @nid
153
- cmd = "fdelete #{s[1]}"
120
+ cmd = "fdelete #{key}\e#{hname}"
154
121
  s[2..-1].each{|c| cmd << " #{c}"}
155
122
  cmd << "\r\n"
156
123
  @log.warn("forward delete #{s[1]}")
157
124
  res = send_cmd(nodes[0], cmd)
158
- if res
159
- return send_data("#{res}\r\n")
125
+ if res == nil || res.start_with?("ERROR")
126
+ return send_data("SERVER_ERROR Message forward failed.\r\n")
160
127
  end
161
- return send_data("SERVER_ERROR Message forward failed.\r\n")
128
+ return send_data("#{res}\r\n")
162
129
  end
163
130
  unless @storages.key?(hname)
164
131
  send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
@@ -166,11 +133,20 @@ module Roma
166
133
  end
167
134
  res = @storages[hname].delete(vn, key, d)
168
135
  @stats.delete_count += 1
136
+
169
137
  return send_data("NOT_DELETED\r\n") unless res
170
138
  return send_data("NOT_FOUND\r\n") if res == :deletemark
171
139
 
140
+ if @stats.wb_command_map.key?(:delete)
141
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:delete], key, res[4])
142
+ end
143
+
172
144
  nodes[1..-1].each{ |nid|
173
- send_cmd(nid,"rdelete #{s[1]} #{res[2]}\r\n")
145
+ res2 = send_cmd(nid,"rdelete #{key}\e#{hname} #{res[2]}\r\n")
146
+ unless res2
147
+ Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('rdelete',[nid,hname,s[1],res[2]]))
148
+ @log.warn("rdelete failed:#{s[1]}\e#{hname} #{d} #{res[2]} -> #{nid}")
149
+ end
174
150
  }
175
151
  return send_data("NOT_FOUND\r\n") unless res[4]
176
152
  send_data("DELETED\r\n")
@@ -193,12 +169,21 @@ module Roma
193
169
  end
194
170
  res = @storages[hname].delete(vn, key, d)
195
171
  @stats.delete_count += 1
172
+
196
173
  return send_data("NOT_DELETED\r\n") unless res
197
174
  return send_data("NOT_FOUND\r\n") if res == :deletemark
198
175
 
176
+ if @stats.wb_command_map.key?(:delete)
177
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:delete], key, res[4])
178
+ end
179
+
199
180
  nodes.delete(@nid)
200
181
  nodes.each{ |nid|
201
- send_cmd(nid,"rdelete #{s[1]} #{res[2]}\r\n")
182
+ res2 = send_cmd(nid,"rdelete #{key}\e#{hname} #{res[2]}\r\n")
183
+ unless res2
184
+ Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('rdelete',[nid,hname,s[1],res[2]]))
185
+ @log.warn("rdelete failed:#{s[1]}\e#{hname} #{d} #{res[2]} -> #{nid}")
186
+ end
202
187
  }
203
188
  return send_data("NOT_FOUND\r\n") unless res[4]
204
189
  send_data("DELETED\r\n")
@@ -221,24 +206,6 @@ module Roma
221
206
  end
222
207
  end
223
208
 
224
- # out <key> <vn>
225
- def ev_out(s)
226
- key,hname = s[1].split("\e")
227
- hname ||= @defhash
228
- if s.length >= 3
229
- vn = s[2].to_i
230
- else
231
- d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
232
- vn = @rttable.get_vnode_id(d)
233
- end
234
- res = @storages[hname].out(vn, key, 0)
235
- @stats.out_message_count += 1
236
- unless res
237
- return send_data("NOT_DELETED\r\n")
238
- end
239
- send_data("DELETED\r\n")
240
- end
241
-
242
209
  # "add" means that "add a new data to a store"
243
210
  # <command name> <key> <flags> <exptime> <bytes> [noreply]\r\n
244
211
  # <data block>\r\n
@@ -277,11 +244,11 @@ module Roma
277
244
  nodes = @rttable.search_nodes_for_write(vn)
278
245
  if nodes[0] != @nid
279
246
  @log.warn("forward cas key=#{key} vn=#{vn} to #{nodes[0]}")
280
- res = send_cmd(nodes[0],"fcas #{s[1]} #{d} #{s[3]} #{v.length} #{s[5]}\r\n#{v}\r\n")
281
- if res
282
- return send_data("#{res}\r\n")
247
+ res = send_cmd(nodes[0],"fcas #{key}\e#{hname} #{d} #{s[3]} #{v.length} #{s[5]}\r\n#{v}\r\n")
248
+ if res == nil || res.start_with?("ERROR")
249
+ return send_data("SERVER_ERROR Message forward failed.\r\n")
283
250
  end
284
- return send_data("SERVER_ERROR Message forward failed.\r\n")
251
+ return send_data("#{res}\r\n")
285
252
  end
286
253
 
287
254
  store_cas(hname, vn, key, d, s[5].to_i, s[3].to_i, v, nodes[1..-1])
@@ -313,6 +280,72 @@ module Roma
313
280
  def ev_decr(s); incr_decr(:decr,s); end
314
281
  def ev_fdecr(s); fincr_fdecr(:decr,s); end
315
282
 
283
+ # set_expt <key> <expt>
284
+ def ev_set_expt(s)
285
+ key,hname = s[1].split("\e")
286
+ hname ||= @defhash
287
+ d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
288
+ vn = @rttable.get_vnode_id(d)
289
+ nodes = @rttable.search_nodes_for_write(vn)
290
+ if nodes[0] != @nid
291
+ @log.warn("forward set_expt key=#{key} vn=#{vn} to #{nodes[0]}")
292
+ res = send_cmd(nodes[0],"fset_expt #{s[1]} #{s[2]}\r\n")
293
+ if res
294
+ return send_data("#{res}\r\n")
295
+ end
296
+ return send_data("SERVER_ERROR Message forward failed.\r\n")
297
+ end
298
+
299
+ unless @storages.key?(hname)
300
+ send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
301
+ return
302
+ end
303
+
304
+ expt = chg_time_expt(s[2].to_i)
305
+ ret = @storages[hname].set_expt(vn, key, d, expt)
306
+
307
+ if ret
308
+ if @stats.wb_command_map.key?(:set_export)
309
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt], k, expt.to_s)
310
+ end
311
+ redundant(nodes[1..-1], hname, key, d, ret[2], ret[3], ret[4])
312
+ send_data("STORED\r\n")
313
+ else
314
+ return send_data("NOT_STORED\r\n")
315
+ end
316
+ end
317
+
318
+ # fset_expt <key> <expt>
319
+ def ev_fset_expt(s)
320
+ key,hname = s[1].split("\e")
321
+ hname ||= @defhash
322
+ d = Digest::SHA1.hexdigest(key).hex % @rttable.hbits
323
+ vn = @rttable.get_vnode_id(d)
324
+ nodes = @rttable.search_nodes_for_write(vn)
325
+ if nodes.include?(@nid) == false
326
+ @log.error("fset_expt failed key = #{s[1]} vn = #{vn}")
327
+ return send_data("SERVER_ERROR Routing table is inconsistent.\r\n")
328
+ end
329
+
330
+ unless @storages.key?(hname)
331
+ send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
332
+ return
333
+ end
334
+
335
+ expt = chg_time_expt(s[2].to_i)
336
+ ret = @storages[hname].set_expt(vn, key, d, expt)
337
+
338
+ if ret
339
+ if @stats.wb_command_map.key?(:set_export)
340
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:set_expt], k, expt.to_s)
341
+ end
342
+ redundant(nodes[1..-1], hname, key, d, ret[2], ret[3], ret[4])
343
+ send_data("STORED\r\n")
344
+ else
345
+ return send_data("NOT_STORED\r\n")
346
+ end
347
+ end
348
+
316
349
  # set_size_of_zredundant <n>
317
350
  def ev_set_size_of_zredundant(s)
318
351
  if s.length != 2 || s[1].to_i == 0
@@ -337,18 +370,30 @@ module Roma
337
370
 
338
371
  def forward_get(nid, k, d)
339
372
  con = get_connection(nid)
340
- con.send("get #{k}\r\n")
373
+ con.send("fget #{k}\r\n")
341
374
  res = con.gets
342
- return res if res == "END\r\n"
343
- s = res.split(/ /)
344
- res << con.read_bytes(s[3].to_i + 2)
345
- res << con.gets
375
+ if res == nil
376
+ @rttable.proc_failed(nid)
377
+ @log.error("forward get failed:nid=#{nid} key=#{k}")
378
+ return nil
379
+ elsif res == "END\r\n"
380
+ # value dose not found
381
+ elsif res.start_with?("ERROR")
382
+ @rttable.proc_succeed(nid)
383
+ con.close_connection
384
+ return nil
385
+ else
386
+ s = res.split(/ /)
387
+ res << con.read_bytes(s[3].to_i + 2)
388
+ res << con.gets
389
+ end
346
390
  return_connection(nid, con)
347
391
  @rttable.proc_succeed(nid)
348
392
  res
349
393
  rescue => e
350
- @rttable.proc_failed(nid)
351
- @log.error("forward get failed:nid=#{nid} key=#{key}")
394
+ @rttable.proc_failed(nid) if e.message != "no connection"
395
+ @log.error("#{e.inspect}/#{$@}")
396
+ @log.error("forward get failed:nid=#{nid} key=#{k}")
352
397
  nil
353
398
  end
354
399
 
@@ -371,18 +416,18 @@ module Roma
371
416
  end
372
417
 
373
418
  def store(fnc, hname, vn, k, d, expt, v, nodes)
374
- if expt == 0
375
- expt = 0x7fffffff
376
- elsif expt < 2592000
377
- expt += Time.now.to_i
378
- end
419
+ expt = chg_time_expt(expt)
379
420
  unless @storages.key?(hname)
380
421
  send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
381
422
  return
382
423
  end
383
424
  ret = @storages[hname].send(fnc, vn, k, d, expt ,v)
384
425
  @stats.write_count += 1
426
+
385
427
  if ret
428
+ if @stats.wb_command_map.key?(fnc)
429
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[fnc], k, ret[4])
430
+ end
386
431
  redundant(nodes, hname, k, d, ret[2], expt, ret[4])
387
432
  send_data("STORED\r\n")
388
433
  else
@@ -392,11 +437,7 @@ module Roma
392
437
  end
393
438
 
394
439
  def store_cas(hname, vn, k, d, clk, expt, v, nodes)
395
- if expt == 0
396
- expt = 0x7fffffff
397
- elsif expt < 2592000
398
- expt += Time.now.to_i
399
- end
440
+ expt = chg_time_expt(expt)
400
441
  unless @storages.key?(hname)
401
442
  send_data("SERVER_ERROR #{hname} dose not exists.\r\n")
402
443
  return
@@ -404,6 +445,7 @@ module Roma
404
445
 
405
446
  ret = @storages[hname].cas(vn, k, d, clk, expt ,v)
406
447
  @stats.write_count += 1
448
+
407
449
  case ret
408
450
  when nil
409
451
  @log.error("cas NOT_STORED:#{hname} #{vn} #{k} #{d} #{expt} #{clk}")
@@ -413,56 +455,34 @@ module Roma
413
455
  when :exists
414
456
  send_data("EXISTS\r\n")
415
457
  else
458
+ if @stats.wb_command_map.key?(:cas)
459
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[:cas], k, ret[4])
460
+ end
416
461
  redundant(nodes, hname, k, d, ret[2], expt, ret[4])
417
462
  send_data("STORED\r\n")
418
463
  end
419
464
  end
420
465
 
421
466
  def redundant(nodes, hname, k, d, clk, expt, v)
422
- if @rttable.min_version == nil || @rttable.min_version < 0x000306 # ver.0.3.6
423
- return redundant_older_than_000306(nodes, hname, k, d, clk, expt, v)
424
- end
425
-
426
467
  if @stats.size_of_zredundant > 0 && @stats.size_of_zredundant < v.length
427
468
  return zredundant(nodes, hname, k, d, clk, expt, v)
428
469
  end
429
470
 
430
471
  nodes.each{ |nid|
431
472
  res = send_cmd(nid,"rset #{k}\e#{hname} #{d} #{clk} #{expt} #{v.length}\r\n#{v}\r\n")
432
- unless res
473
+ if res == nil || res.start_with?("ERROR")
433
474
  Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('redundant',[nid,hname,k,d,clk,expt,v]))
434
475
  @log.warn("redundant failed:#{k}\e#{hname} #{d} #{clk} #{expt} #{v.length} -> #{nid}")
435
476
  end
436
477
  }
437
478
  end
438
479
 
439
- def redundant_older_than_000306(nodes, hname, k, d, clk, expt, v)
440
- nodes.each{ |nid|
441
- if @rttable.version_of_nodes[nid] >= 0x000306 &&
442
- @stats.size_of_zredundant > 0 && @stats.size_of_zredundant < v.length
443
-
444
- zv = Zlib::Deflate.deflate(v) unless zv
445
- res = send_cmd(nid,"rzset #{k}\e#{hname} #{d} #{clk} #{expt} #{zv.length}\r\n#{zv}\r\n")
446
- unless res
447
- Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('zredundant',[nid,hname,k,d,clk,expt,zv]))
448
- @log.warn("redundant_older_than_000306 failed:#{k}\e#{hname} #{d} #{clk} #{expt} #{zv.length} -> #{nid}")
449
- end
450
- else
451
- res = send_cmd(nid,"rset #{k}\e#{hname} #{d} #{clk} #{expt} #{v.length}\r\n#{v}\r\n")
452
- unless res
453
- Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('redundant',[nid,hname,k,d,clk,expt,v]))
454
- @log.warn("redundant_older_than_000306 failed:#{k}\e#{hname} #{d} #{clk} #{expt} #{v.length} -> #{nid}")
455
- end
456
- end
457
- }
458
- end
459
-
460
480
  def zredundant(nodes, hname, k, d, clk, expt, v)
461
481
  zv = Zlib::Deflate.deflate(v)
462
482
 
463
483
  nodes.each{ |nid|
464
484
  res = send_cmd(nid,"rzset #{k}\e#{hname} #{d} #{clk} #{expt} #{zv.length}\r\n#{zv}\r\n")
465
- unless res
485
+ if res == nil || res.start_with?("ERROR")
466
486
  Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('zredundant',[nid,hname,k,d,clk,expt,zv]))
467
487
  @log.warn("zredundant failed:#{k}\e#{hname} #{d} #{clk} #{expt} #{zv.length} -> #{nid}")
468
488
  end
@@ -480,10 +500,10 @@ module Roma
480
500
  if nodes[0] != @nid
481
501
  @log.warn("forward #{fnc} key=#{key} vn=#{vn} to #{nodes[0]}")
482
502
  res = send_cmd(nodes[0],"f#{fnc} #{s[1]} #{d} #{s[3]} #{v.length}\r\n#{v}\r\n")
483
- if res
484
- return send_data("#{res}\r\n")
503
+ if res == nil || res.start_with?("ERROR")
504
+ return send_data("SERVER_ERROR Message forward failed.\r\n")
485
505
  end
486
- return send_data("SERVER_ERROR Message forward failed.\r\n")
506
+ return send_data("#{res}\r\n")
487
507
  end
488
508
 
489
509
  store(fnc, hname, vn, key, d, s[3].to_i, v, nodes[1..-1])
@@ -514,7 +534,11 @@ module Roma
514
534
  end
515
535
  res = @storages[hname].send(fnc, vn, k, d, v)
516
536
  @stats.write_count += 1
537
+
517
538
  if res
539
+ if @stats.wb_command_map.key?(fnc)
540
+ Roma::WriteBehindProcess::push(hname, @stats.wb_command_map[fnc], k, res[4])
541
+ end
518
542
  redundant(nodes, hname, k, d, res[2], res[3], res[4])
519
543
  send_data("#{res[4]}\r\n")
520
544
  else
@@ -532,10 +556,10 @@ module Roma
532
556
  if nodes[0] != @nid
533
557
  @log.debug("forward #{fnc} key=#{s[1]} vn=#{vn} to #{nodes[0]}")
534
558
  res = send_cmd(nodes[0],"f#{fnc} #{s[1]} #{d} #{s[2]}\r\n")
535
- if res
536
- return send_data("#{res}\r\n")
559
+ if res == nil || res.start_with?("ERROR")
560
+ return send_data("SERVER_ERROR Message forward failed.\r\n")
537
561
  end
538
- return send_data("SERVER_ERROR Message forward failed.\r\n")
562
+ return send_data("#{res}\r\n")
539
563
  end
540
564
 
541
565
  store_incr_decr(fnc, hname, vn, key, d, v, nodes[1..-1])
@@ -558,7 +582,7 @@ module Roma
558
582
  store_incr_decr(fnc, hname, vn, key, d, v, nodes)
559
583
  end
560
584
 
561
- end # module StorageCommandReceiver
585
+ end # module PluginStorage
562
586
 
563
- end # module Command
587
+ end # module CommandPlugin
564
588
  end # module Roma