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.
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