droonga-engine 1.0.5 → 1.0.6

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/bin/droonga-engine-absorb-data +2 -1
  3. data/bin/droonga-engine-catalog-generate +21 -5
  4. data/bin/droonga-engine-catalog-modify +22 -6
  5. data/bin/droonga-engine-configure +215 -0
  6. data/bin/droonga-engine-join +48 -123
  7. data/bin/droonga-engine-unjoin +14 -1
  8. data/doc/text/news.md +21 -0
  9. data/droonga-engine.gemspec +12 -10
  10. data/install/centos/droonga-engine +60 -0
  11. data/install/centos/functions.sh +35 -0
  12. data/install/debian/droonga-engine +155 -0
  13. data/install/debian/functions.sh +33 -0
  14. data/install.sh +360 -0
  15. data/lib/droonga/address.rb +3 -1
  16. data/lib/droonga/catalog/dataset.rb +2 -0
  17. data/lib/droonga/catalog/version1.rb +16 -3
  18. data/lib/droonga/catalog/version2.rb +16 -3
  19. data/lib/droonga/catalog_fetcher.rb +51 -0
  20. data/lib/droonga/catalog_generator.rb +6 -5
  21. data/lib/droonga/catalog_modifier.rb +45 -0
  22. data/lib/droonga/command/droonga_engine.rb +96 -29
  23. data/lib/droonga/command/droonga_engine_service.rb +5 -0
  24. data/lib/droonga/command/remote.rb +368 -0
  25. data/lib/droonga/command/serf_event_handler.rb +37 -304
  26. data/lib/droonga/dispatcher.rb +15 -1
  27. data/lib/droonga/engine/version.rb +1 -1
  28. data/lib/droonga/engine.rb +11 -4
  29. data/lib/droonga/engine_state.rb +2 -0
  30. data/lib/droonga/farm.rb +14 -5
  31. data/lib/droonga/fluent_message_receiver.rb +23 -6
  32. data/lib/droonga/fluent_message_sender.rb +5 -1
  33. data/lib/droonga/node_status.rb +67 -0
  34. data/lib/droonga/path.rb +28 -4
  35. data/lib/droonga/plugins/catalog.rb +40 -0
  36. data/lib/droonga/safe_file_writer.rb +1 -1
  37. data/lib/droonga/searcher.rb +3 -15
  38. data/lib/droonga/serf.rb +17 -32
  39. data/lib/droonga/serf_downloader.rb +26 -1
  40. data/lib/droonga/service_installation.rb +123 -0
  41. data/lib/droonga/session.rb +4 -0
  42. data/lib/droonga/slice.rb +22 -12
  43. data/lib/droonga/supervisor.rb +16 -2
  44. data/lib/droonga/worker_process_agent.rb +13 -1
  45. data/sample/droonga-engine.yaml +5 -0
  46. data/test/command/config/default/catalog.json +1 -1
  47. data/test/command/config/default/droonga-engine.yaml +4 -0
  48. data/test/command/config/version1/catalog.json +1 -1
  49. data/test/command/suite/catalog/fetch.expected +64 -0
  50. data/test/command/suite/catalog/fetch.test +6 -0
  51. data/test/unit/catalog/test_version1.rb +2 -2
  52. data/test/unit/catalog/test_version2.rb +3 -3
  53. data/test/unit/helper/sandbox.rb +3 -1
  54. data/test/unit/plugins/catalog/test_fetch.rb +76 -0
  55. data/test/unit/test_catalog_generator.rb +7 -3
  56. metadata +74 -27
  57. data/bin/droonga-engine-data-publisher +0 -66
data/lib/droonga/path.rb CHANGED
@@ -34,6 +34,10 @@ module Droonga
34
34
  ENV[BASE_DIR_ENV_NAME] = new_base
35
35
  end
36
36
 
37
+ def databases
38
+ base + "database"
39
+ end
40
+
37
41
  def state
38
42
  base + "state"
39
43
  end
@@ -50,18 +54,38 @@ module Droonga
50
54
  state + "effective-message.timestamp"
51
55
  end
52
56
 
57
+ def config
58
+ base + "droonga-engine.yaml"
59
+ end
60
+
61
+ def default_pid_file
62
+ base + "droonga-engine.pid"
63
+ end
64
+
65
+ def default_log_file
66
+ base + "droonga-engine.log"
67
+ end
68
+
53
69
  def catalog
54
70
  base_file_name = ENV["DROONGA_CATALOG"] || "catalog.json"
55
71
  Pathname.new(base_file_name).expand_path(base)
56
72
  end
57
73
 
58
- def published(suffix)
59
- base + "published-#{suffix}"
60
- end
61
-
62
74
  def buffer
63
75
  state + "buffer"
64
76
  end
77
+
78
+ def serf_event_handler_errors
79
+ state + "serf-event-handler-errors"
80
+ end
81
+
82
+ def serf_event_handler_error_file
83
+ now = Time.now
84
+ name = sprintf("%04d-%02d-%02d_%02d-%02d-%02d.%d.error",
85
+ now.year, now.month, now.day,
86
+ now.hour, now.min, now.sec, now.nsec)
87
+ serf_event_handler_errors + name
88
+ end
65
89
  end
66
90
  end
67
91
  end
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2013-2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
+
16
+ require "droonga/plugin"
17
+ require "droonga/path"
18
+
19
+ module Droonga
20
+ module Plugins
21
+ module Catalog
22
+ extend Plugin
23
+ register("catalog")
24
+
25
+ class FetchHandler < Droonga::Handler
26
+ action.synchronous = false
27
+
28
+ def handle(message)
29
+ JSON.parse(Path.catalog.read)
30
+ end
31
+ end
32
+
33
+ define_single_step do |step|
34
+ step.name = "catalog.fetch"
35
+ step.handler = FetchHandler
36
+ step.collector = Collectors::Or
37
+ end
38
+ end
39
+ end
40
+ end
@@ -26,7 +26,7 @@ module Droonga
26
26
  FileUtils.mkdir_p(path.dirname.to_s)
27
27
  Tempfile.open(path.basename.to_s, path.dirname.to_s, "w") do |output|
28
28
  if block_given?
29
- yield(output)
29
+ yield(output, output.path)
30
30
  else
31
31
  output.write(contents)
32
32
  end
@@ -82,26 +82,14 @@ module Droonga
82
82
  def search(queries)
83
83
  outputs = nil
84
84
  logger.trace("search: start", :queries => queries)
85
- # TODO: THIS IS JUST A WORKAROUND! We should remove it ASAP!
86
- disable_gc do
87
- @context.push_memory_pool do
88
- outputs = process_queries(queries)
89
- end
85
+ @context.push_memory_pool do
86
+ outputs = process_queries(queries)
90
87
  end
91
88
  logger.trace("search: done")
92
- return outputs
89
+ outputs
93
90
  end
94
91
 
95
92
  private
96
- def disable_gc
97
- GC.disable
98
- begin
99
- yield
100
- ensure
101
- GC.enable
102
- end
103
- end
104
-
105
93
  def process_queries(queries)
106
94
  logger.trace("process_queries: start")
107
95
  if queries.nil? or queries.empty?
data/lib/droonga/serf.rb CHANGED
@@ -22,6 +22,7 @@ require "open3"
22
22
  require "droonga/path"
23
23
  require "droonga/loggable"
24
24
  require "droonga/catalog_loader"
25
+ require "droonga/node_status"
25
26
  require "droonga/serf_downloader"
26
27
  require "droonga/line_buffer"
27
28
 
@@ -43,32 +44,6 @@ module Droonga
43
44
  def path
44
45
  Droonga::Path.base + "serf"
45
46
  end
46
-
47
- def status_file
48
- Droonga::Path.state + "status_file"
49
- end
50
-
51
- def load_status
52
- if status_file.exist?
53
- contents = status_file.read
54
- unless contents.empty?
55
- return JSON.parse(contents, :symbolize_names => true)
56
- end
57
- end
58
- {}
59
- end
60
-
61
- def status(key)
62
- load_status[key]
63
- end
64
-
65
- def send_query(name, query, payload)
66
- new(nil, name).send_query(query, payload)
67
- end
68
-
69
- def live_nodes(name)
70
- new(nil, name).live_nodes
71
- end
72
47
  end
73
48
 
74
49
  include Loggable
@@ -111,11 +86,20 @@ module Droonga
111
86
  logger.trace("stop: done")
112
87
  end
113
88
 
89
+ def join(*hosts)
90
+ ensure_serf
91
+ nodes = hosts.collect do |host|
92
+ "#{host}:#{port}"
93
+ end
94
+ run_once("join", *nodes)
95
+ end
96
+
114
97
  def send_query(query, payload)
115
98
  ensure_serf
116
99
  options = ["-format", "json"] + additional_options_from_payload(payload)
117
100
  options += [query, JSON.generate(payload)]
118
101
  result = run_once("query", *options)
102
+ result[:result] = JSON.parse(result[:result])
119
103
  if payload["node"]
120
104
  responses = result[:result]["Responses"]
121
105
  response = responses[payload["node"]]
@@ -135,7 +119,8 @@ module Droonga
135
119
  def live_nodes
136
120
  ensure_serf
137
121
  nodes = {}
138
- result= run_once("members", "-format", "json")
122
+ result = run_once("members", "-format", "json")
123
+ result[:result] = JSON.parse(result[:result])
139
124
  members = result[:result]
140
125
  members["members"].each do |member|
141
126
  if member["status"] == "alive"
@@ -212,13 +197,13 @@ module Droonga
212
197
  "#{extract_host(@name)}:7373"
213
198
  end
214
199
 
215
- def status
216
- @status ||= self.class.load_status
200
+ def node_status
201
+ @node_status ||= NodeStatus.new
217
202
  end
218
203
 
219
204
  def role
220
- if status[:role]
221
- role = status[:role].to_sym
205
+ if node_status.have?(:role)
206
+ role = node_status.get(:role).to_sym
222
207
  if self.class::ROLE.key?(role)
223
208
  return role
224
209
  end
@@ -282,7 +267,7 @@ module Droonga
282
267
  def run_once
283
268
  stdout, stderror, status = Open3.capture3(@serf, @command, *@options, :pgroup => true)
284
269
  {
285
- :result => JSON.parse(stdout),
270
+ :result => stdout,
286
271
  :error => stderror,
287
272
  :status => status,
288
273
  }
@@ -27,8 +27,15 @@ module Droonga
27
27
  class SerfDownloader
28
28
  include Loggable
29
29
 
30
+ class DownloadFailed < StandardError
31
+ end
32
+
33
+ MAX_RETRY_COUNT = 5
34
+ RETRY_INTERVAL = 10
35
+
30
36
  def initialize(output_path)
31
37
  @output_path = output_path
38
+ @retry_count = 0
32
39
  end
33
40
 
34
41
  def download
@@ -49,6 +56,24 @@ module Droonga
49
56
  FileUtils.mv("#{dir}/serf", absolete_output_path.to_s)
50
57
  FileUtils.chmod(0755, absolete_output_path.to_s)
51
58
  end
59
+ rescue Archive::Zip::UnzipError => archive_error
60
+ logger.warn("Downloaded zip file is broken.")
61
+ if @retry_count < MAX_RETRY_COUNT
62
+ @retry_count += 1
63
+ sleep(RETRY_INTERVAL * @retry_count)
64
+ download
65
+ else
66
+ raise DownloadFailed.new("Couldn't download serf executable. Try it later.")
67
+ end
68
+ rescue Faraday::ConnectionFailed => network_error
69
+ logger.warn("Connection failed.")
70
+ if @retry_count < MAX_RETRY_COUNT
71
+ @retry_count += 1
72
+ sleep(RETRY_INTERVAL * @retry_count)
73
+ download
74
+ else
75
+ raise DownloadFailed.new("Couldn't download serf executable. Try it later.")
76
+ end
52
77
  end
53
78
 
54
79
  private
@@ -77,7 +102,7 @@ module Droonga
77
102
  when /x86_64|x64/
78
103
  @architecture = "amd64"
79
104
  when /i\d86/
80
- @architecture = "i386"
105
+ @architecture = "386"
81
106
  else
82
107
  raise "Unsupported architecture: #{RUBY_PLATFORM}"
83
108
  end
@@ -0,0 +1,123 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
+
16
+ require "fileutils"
17
+
18
+ require "droonga/path"
19
+
20
+ module Droonga
21
+ class ServiceInstallation
22
+ class << self
23
+ end
24
+
25
+ class NotInstalledAsService < StandardError
26
+ end
27
+
28
+ def user_name
29
+ "droonga-engine"
30
+ end
31
+
32
+ def group_name
33
+ "droonga"
34
+ end
35
+
36
+ def base_directory
37
+ @base_directory ||= Pathname("/home/#{user_name}/droonga")
38
+ end
39
+
40
+ def ensure_using_service_base_directory
41
+ if user_exist?
42
+ Path.base = base_directory.to_s
43
+ end
44
+ end
45
+
46
+ def have_read_permission?
47
+ test_file = Path.config
48
+ begin
49
+ test_file.read
50
+ rescue Errno::EACCES => error
51
+ return false
52
+ end
53
+ true
54
+ end
55
+
56
+ def have_write_permission?
57
+ test_file = Path.base + "#{Time.now.to_i}.test"
58
+ begin
59
+ FileUtils.mkdir_p(Path.base)
60
+ FileUtils.touch(test_file.to_s)
61
+ rescue Errno::EACCES => error
62
+ end
63
+ unless test_file.exist?
64
+ return false
65
+ end
66
+ FileUtils.rm_f(test_file.to_s)
67
+ true
68
+ end
69
+
70
+ def user_exist?
71
+ system("id", user_name,
72
+ :out => "/dev/null",
73
+ :err => "/dev/null")
74
+ end
75
+
76
+ def installed_as_service?
77
+ return false unless user_exist?
78
+
79
+ #TODO: we should support systemd also...
80
+ succeeded = system("service", "droonga-engine", "status",
81
+ :out => "/dev/null",
82
+ :err => "/dev/null")
83
+ return true if succeeded
84
+
85
+ #TODO: we should support systemd also...
86
+ result = `service droonga-engine status`
87
+ result.include?("running") or \
88
+ result.include?("droonga-engine is stopped") or \
89
+ result.include?("droonga-engine dead")
90
+ end
91
+
92
+ def ensure_correct_file_permission(file)
93
+ if user_exist?
94
+ FileUtils.chown_R(user_name, group_name, file)
95
+ FileUtils.chmod_R("go+r", file)
96
+ end
97
+ end
98
+
99
+ def running?(pid_file_path=nil)
100
+ raise NotInstalledAsService.new unless installed_as_service?
101
+ #TODO: we should support systemd also...
102
+ system("service", "droonga-engine", "status",
103
+ :out => "/dev/null",
104
+ :err => "/dev/null")
105
+ end
106
+
107
+ def start
108
+ raise NotInstalledAsService.new unless installed_as_service?
109
+ #TODO: we should support systemd also...
110
+ system("service", "droonga-engine", "start",
111
+ :out => "/dev/null",
112
+ :err => "/dev/null")
113
+ end
114
+
115
+ def stop
116
+ raise NotInstalledAsService.new unless installed_as_service?
117
+ #TODO: we should support systemd also...
118
+ system("service", "droonga-engine", "stop",
119
+ :out => "/dev/null",
120
+ :err => "/dev/null")
121
+ end
122
+ end
123
+ end
@@ -13,8 +13,12 @@
13
13
  # License along with this library; if not, write to the Free Software
14
14
  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
15
 
16
+ require "droonga/loggable"
17
+
16
18
  module Droonga
17
19
  class Session
20
+ include Loggable
21
+
18
22
  def initialize(id, dispatcher, collector_runner, tasks, inputs)
19
23
  @id = id
20
24
  @dispatcher = dispatcher
data/lib/droonga/slice.rb CHANGED
@@ -24,7 +24,7 @@ module Droonga
24
24
  class Slice
25
25
  include Loggable
26
26
 
27
- attr_accessor :on_ready
27
+ attr_writer :on_ready
28
28
  def initialize(dataset, loop, options={})
29
29
  @dataset = dataset
30
30
  @loop = loop
@@ -44,12 +44,29 @@ module Droonga
44
44
  start_supervisor
45
45
  end
46
46
 
47
- def shutdown
48
- logger.trace("shutdown: start")
49
- shutdown_supervisor if @supervisor
47
+ def stop_gracefully
48
+ logger.trace("stop_gracefully: start")
49
+ on_stop = lambda do
50
+ @job_pusher.shutdown
51
+ @processor.shutdown
52
+ yield if block_given?
53
+ end
54
+ if @supervisor
55
+ @supervisor.stop_gracefully do
56
+ on_stop.call
57
+ end
58
+ else
59
+ on_stop.call
60
+ end
61
+ logger.trace("stop_gracefully: done")
62
+ end
63
+
64
+ def stop_immediately
65
+ logger.trace("stop_immediately: start")
66
+ @supervisor.stop_immediately if @supervisor
50
67
  @job_pusher.shutdown
51
68
  @processor.shutdown
52
- logger.trace("shutdown: done")
69
+ logger.trace("stop_immediately: done")
53
70
  end
54
71
 
55
72
  def process(message)
@@ -106,13 +123,6 @@ module Droonga
106
123
  @supervisor.start
107
124
  end
108
125
 
109
- def shutdown_supervisor
110
- logger.trace("supervisor: shutdown: start")
111
- @supervisor.stop_gracefully
112
- logger.trace("supervisor: shutdown: done")
113
- end
114
-
115
- private
116
126
  def on_ready
117
127
  @on_ready.call if @on_ready
118
128
  end
@@ -45,9 +45,18 @@ module Droonga
45
45
  end
46
46
 
47
47
  def stop_gracefully
48
+ logger.trace("stop_gracefully: start")
49
+ n_worker_runners = @worker_runners.size
50
+ n_done_worker_runners = 0
48
51
  @worker_runners.each do |worker_runner|
49
- worker_runner.stop_gracefully
52
+ worker_runner.stop_gracefully do
53
+ n_done_worker_runners += 1
54
+ if n_done_worker_runners == n_worker_runners
55
+ yield if block_given?
56
+ end
57
+ end
50
58
  end
59
+ logger.trace("stop_gracefully: done")
51
60
  end
52
61
 
53
62
  def stop_immediately
@@ -87,6 +96,7 @@ module Droonga
87
96
  @config = config
88
97
  @on_ready = nil
89
98
  @on_failure = nil
99
+ @stop_gracefully_callback = nil
90
100
  end
91
101
 
92
102
  def start
@@ -117,8 +127,11 @@ module Droonga
117
127
  @supervisor.start
118
128
  end
119
129
 
120
- def stop_gracefully
130
+ def stop_gracefully(&block)
131
+ logger.trace("stop_gracefully: start")
121
132
  @supervisor.stop_gracefully
133
+ @stop_gracefully_callback = block
134
+ logger.trace("stop_gracefully: done")
122
135
  end
123
136
 
124
137
  def stop_immediately
@@ -159,6 +172,7 @@ module Droonga
159
172
  @success = status.success?
160
173
  @supervisor.stop
161
174
  on_failure unless success?
175
+ @stop_gracefully_callback.call if @stop_gracefully_callback
162
176
  end
163
177
 
164
178
  private
@@ -17,10 +17,12 @@ require "coolio"
17
17
 
18
18
  require "droonga/process_control_protocol"
19
19
  require "droonga/line_buffer"
20
+ require "droonga/loggable"
20
21
 
21
22
  module Droonga
22
23
  class WorkerProcessAgent
23
24
  include ProcessControlProtocol
25
+ include Loggable
24
26
 
25
27
  def initialize(loop, input, output)
26
28
  @loop = loop
@@ -31,20 +33,26 @@ module Droonga
31
33
  end
32
34
 
33
35
  def start
36
+ logger.trace("start: start")
34
37
  @loop.attach(@input)
35
38
  @loop.attach(@output)
39
+ logger.trace("start: done")
36
40
  end
37
41
 
38
42
  def stop
43
+ logger.trace("stop: start")
39
44
  if @output
40
45
  @output, output = nil, @output
41
46
  output.write(Messages::FINISH)
42
- output.close
47
+ output.on_write_complete do
48
+ output.close
49
+ end
43
50
  end
44
51
  if @input
45
52
  @input, input = nil, @input
46
53
  input.close
47
54
  end
55
+ logger.trace("stop: done")
48
56
  end
49
57
 
50
58
  def ready
@@ -107,5 +115,9 @@ module Droonga
107
115
  def on_stop_immediately
108
116
  @on_stop_immediately.call if @on_stop_immediately
109
117
  end
118
+
119
+ def log_tag
120
+ "worker_process_agent"
121
+ end
110
122
  end
111
123
  end
@@ -0,0 +1,5 @@
1
+ host: 192.168.0.10
2
+ port: 10031
3
+ tag: droonga
4
+ log_file: droonga-engine.log
5
+ log_level: info
@@ -4,7 +4,7 @@
4
4
  "datasets": {
5
5
  "Default": {
6
6
  "nWorkers": 2,
7
- "plugins": ["groonga", "crud", "search", "dump", "system"],
7
+ "plugins": ["groonga", "crud", "search", "dump", "system", "catalog"],
8
8
  "replicas": [
9
9
  {
10
10
  "dimension": "_key",
@@ -0,0 +1,4 @@
1
+ host: 127.0.0.1
2
+ port: 10031
3
+ tag: droonga
4
+ daemon: false
@@ -11,7 +11,7 @@
11
11
  "datasets": {
12
12
  "Default": {
13
13
  "workers": 2,
14
- "plugins": ["groonga", "crud", "search", "dump", "system"],
14
+ "plugins": ["groonga", "crud", "search", "dump", "system", "catalog"],
15
15
  "number_of_replicas": 2,
16
16
  "number_of_partitions": 2,
17
17
  "partition_key": "_key",
@@ -0,0 +1,64 @@
1
+ {
2
+ "inReplyTo": "request-id",
3
+ "statusCode": 200,
4
+ "type": "catalog.fetch.result",
5
+ "body": {
6
+ "version": 2,
7
+ "effectiveDate": "2014-02-28T00:00:00Z",
8
+ "datasets": {
9
+ "Default": {
10
+ "nWorkers": 2,
11
+ "plugins": [
12
+ "groonga",
13
+ "crud",
14
+ "search",
15
+ "dump",
16
+ "system",
17
+ "catalog"
18
+ ],
19
+ "replicas": [
20
+ {
21
+ "dimension": "_key",
22
+ "slicer": "hash",
23
+ "slices": [
24
+ {
25
+ "label": "slice000",
26
+ "weight": 50,
27
+ "volume": {
28
+ "address": "127.0.0.1:23003/droonga.000"
29
+ }
30
+ },
31
+ {
32
+ "label": "slice001",
33
+ "weight": 50,
34
+ "volume": {
35
+ "address": "127.0.0.1:23003/droonga.001"
36
+ }
37
+ }
38
+ ]
39
+ },
40
+ {
41
+ "dimension": "_key",
42
+ "slicer": "hash",
43
+ "slices": [
44
+ {
45
+ "label": "slice010",
46
+ "weight": 50,
47
+ "volume": {
48
+ "address": "127.0.0.1:23003/droonga.010"
49
+ }
50
+ },
51
+ {
52
+ "label": "slice011",
53
+ "weight": 50,
54
+ "volume": {
55
+ "address": "127.0.0.1:23003/droonga.011"
56
+ }
57
+ }
58
+ ]
59
+ }
60
+ ]
61
+ }
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,6 @@
1
+ #@require-catalog-version 2
2
+ {
3
+ "type": "catalog.fetch",
4
+ "dataset": "Default",
5
+ "body": {}
6
+ }