droonga-engine 1.0.9 → 1.1.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/benchmark/timer-watcher/benchmark.rb +44 -0
- data/bin/droonga-engine-absorb-data +246 -187
- data/bin/droonga-engine-catalog-generate +12 -12
- data/bin/droonga-engine-catalog-modify +4 -4
- data/bin/droonga-engine-join +352 -171
- data/bin/droonga-engine-set-role +54 -0
- data/bin/droonga-engine-unjoin +107 -112
- data/droonga-engine.gemspec +3 -3
- data/install.sh +55 -36
- data/install/centos/functions.sh +2 -2
- data/install/debian/functions.sh +2 -2
- data/lib/droonga/address.rb +26 -24
- data/lib/droonga/buffered_tcp_socket.rb +65 -10
- data/lib/droonga/catalog/base.rb +9 -6
- data/lib/droonga/catalog/dataset.rb +17 -41
- data/lib/droonga/catalog/fetcher.rb +64 -0
- data/lib/droonga/catalog/generator.rb +245 -0
- data/lib/droonga/catalog/loader.rb +66 -0
- data/lib/droonga/{catalog_modifier.rb → catalog/modifier.rb} +11 -18
- data/lib/droonga/catalog/replicas_volume.rb +123 -0
- data/lib/droonga/catalog/schema.rb +37 -37
- data/lib/droonga/catalog/single_volume.rb +11 -3
- data/lib/droonga/catalog/slice.rb +10 -6
- data/lib/droonga/catalog/{collection_volume.rb → slices_volume.rb} +47 -11
- data/lib/droonga/catalog/version1.rb +47 -19
- data/lib/droonga/catalog/version2.rb +11 -10
- data/lib/droonga/catalog/version2_validator.rb +4 -4
- data/lib/droonga/catalog/volume.rb +17 -5
- data/lib/droonga/changable.rb +25 -0
- data/lib/droonga/cluster.rb +237 -0
- data/lib/droonga/collector_runner.rb +4 -0
- data/lib/droonga/collectors.rb +2 -1
- data/lib/droonga/collectors/recursive_sum.rb +26 -0
- data/lib/droonga/command/droonga_engine.rb +404 -127
- data/lib/droonga/command/droonga_engine_service.rb +47 -11
- data/lib/droonga/command/droonga_engine_worker.rb +21 -1
- data/lib/droonga/command/remote_command_base.rb +78 -0
- data/lib/droonga/command/serf_event_handler.rb +29 -20
- data/lib/droonga/data_absorber_client.rb +222 -0
- data/lib/droonga/database_scanner.rb +106 -0
- data/lib/droonga/{live_nodes_list_loader.rb → deferrable.rb} +11 -24
- data/lib/droonga/differ.rb +58 -0
- data/lib/droonga/dispatcher.rb +155 -32
- data/lib/droonga/distributed_command_planner.rb +9 -11
- data/lib/droonga/engine.rb +83 -78
- data/lib/droonga/engine/version.rb +1 -1
- data/lib/droonga/engine_node.rb +301 -0
- data/lib/droonga/engine_state.rb +62 -40
- data/lib/droonga/farm.rb +44 -5
- data/lib/droonga/file_observer.rb +16 -12
- data/lib/droonga/fluent_message_receiver.rb +98 -29
- data/lib/droonga/fluent_message_sender.rb +30 -23
- data/lib/droonga/forward_buffer.rb +160 -0
- data/lib/droonga/forwarder.rb +73 -40
- data/lib/droonga/handler.rb +7 -6
- data/lib/droonga/handler_messenger.rb +15 -6
- data/lib/droonga/handler_runner.rb +6 -1
- data/lib/droonga/internal_fluent_message_receiver.rb +28 -8
- data/lib/droonga/job_pusher.rb +10 -7
- data/lib/droonga/job_receiver.rb +6 -4
- data/lib/droonga/logger.rb +7 -1
- data/lib/droonga/node_name.rb +90 -0
- data/lib/droonga/node_role.rb +72 -0
- data/lib/droonga/path.rb +34 -9
- data/lib/droonga/planner.rb +73 -7
- data/lib/droonga/plugin/async_command.rb +154 -0
- data/lib/droonga/plugins/catalog.rb +1 -0
- data/lib/droonga/plugins/crud.rb +22 -6
- data/lib/droonga/plugins/dump.rb +66 -135
- data/lib/droonga/plugins/groonga/delete.rb +13 -0
- data/lib/droonga/plugins/search/distributed_search_planner.rb +4 -4
- data/lib/droonga/plugins/system.rb +5 -26
- data/lib/droonga/plugins/system/absorb_data.rb +405 -0
- data/lib/droonga/plugins/system/statistics.rb +71 -0
- data/lib/droonga/plugins/system/status.rb +53 -0
- data/lib/droonga/process_control_protocol.rb +3 -1
- data/lib/droonga/process_supervisor.rb +32 -15
- data/lib/droonga/reducer.rb +69 -0
- data/lib/droonga/safe_file_writer.rb +1 -1
- data/lib/droonga/serf.rb +207 -276
- data/lib/droonga/serf/agent.rb +228 -0
- data/lib/droonga/serf/command.rb +94 -0
- data/lib/droonga/serf/downloader.rb +120 -0
- data/lib/droonga/serf/remote_command.rb +348 -0
- data/lib/droonga/serf/tag.rb +56 -0
- data/lib/droonga/service_installation.rb +2 -2
- data/lib/droonga/session.rb +49 -1
- data/lib/droonga/single_step.rb +6 -11
- data/lib/droonga/single_step_definition.rb +32 -1
- data/lib/droonga/slice.rb +14 -9
- data/lib/droonga/supervisor.rb +27 -20
- data/lib/droonga/test/stub_handler_messenger.rb +2 -1
- data/lib/droonga/timestamp.rb +69 -0
- data/lib/droonga/worker_process_agent.rb +33 -15
- data/sample/cluster-state.json +8 -0
- data/sample/cluster/Rakefile +30 -6
- data/test/command/fixture/integer-key-table.jsons +11 -0
- data/test/command/fixture/string-key-table.jsons +11 -0
- data/test/command/run-test.rb +4 -0
- data/test/command/suite/add/error/invalid-integer.expected +3 -3
- data/test/command/suite/add/error/invalid-time.expected +3 -3
- data/test/command/suite/add/{minimum.expected → key-integer.expected} +0 -0
- data/test/command/suite/add/{minimum.test → key-integer.test} +0 -0
- data/test/command/suite/add/key-string.expected +6 -0
- data/test/command/suite/add/key-string.test +9 -0
- data/test/command/suite/add/mismatched-key-type/acceptable/integer-for-string.expected +6 -0
- data/test/command/suite/add/mismatched-key-type/acceptable/integer-for-string.test +9 -0
- data/test/command/suite/add/mismatched-key-type/acceptable/string-for-integer.expected +6 -0
- data/test/command/suite/add/mismatched-key-type/acceptable/string-for-integer.test +9 -0
- data/test/command/suite/add/without-values.expected +6 -0
- data/test/command/suite/add/without-values.test +11 -0
- data/test/command/suite/dump/column/index.expected +33 -1
- data/test/command/suite/dump/column/index.test +1 -0
- data/test/command/suite/dump/column/scalar.expected +29 -1
- data/test/command/suite/dump/column/scalar.test +1 -0
- data/test/command/suite/dump/column/vector.expected +29 -1
- data/test/command/suite/dump/column/vector.test +1 -0
- data/test/command/suite/dump/record/scalar.catalog.json +12 -0
- data/test/command/suite/dump/record/scalar.expected +84 -0
- data/test/command/suite/dump/record/scalar.test +16 -0
- data/test/command/suite/dump/record/vector/reference.expected +83 -1
- data/test/command/suite/dump/record/vector/reference.test +1 -0
- data/test/command/suite/dump/table/array.expected +27 -1
- data/test/command/suite/dump/table/array.test +1 -0
- data/test/command/suite/dump/table/double_array_trie.expected +27 -1
- data/test/command/suite/dump/table/double_array_trie.test +1 -0
- data/test/command/suite/dump/table/hash.expected +27 -1
- data/test/command/suite/dump/table/hash.test +1 -0
- data/test/command/suite/dump/table/patricia_trie.expected +27 -1
- data/test/command/suite/dump/table/patricia_trie.test +1 -0
- data/test/command/suite/groonga/delete/{success.expected → key-integer.expected} +0 -0
- data/test/command/suite/groonga/delete/key-integer.test +17 -0
- data/test/command/suite/groonga/delete/key-string.expected +19 -0
- data/test/command/suite/groonga/delete/{success.test → key-string.test} +4 -6
- data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/integer-for-string.expected +19 -0
- data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/integer-for-string.test +17 -0
- data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/string-for-integer.expected +19 -0
- data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/string-for-integer.test +17 -0
- data/test/command/suite/message/error/missing-dataset.test +1 -0
- data/test/command/suite/system/absorb-data/records.catalog.json +58 -0
- data/test/command/suite/system/absorb-data/records.expected +32 -0
- data/test/command/suite/system/absorb-data/records.test +24 -0
- data/test/command/suite/system/statistics/object/count/empty.expected +11 -0
- data/test/command/suite/system/statistics/object/count/empty.test +12 -0
- data/test/command/suite/system/statistics/object/count/per-volume/empty.catalog.json +36 -0
- data/test/command/suite/system/statistics/object/count/per-volume/empty.expected +19 -0
- data/test/command/suite/system/statistics/object/count/per-volume/empty.test +12 -0
- data/test/command/suite/system/statistics/object/count/per-volume/record.catalog.json +40 -0
- data/test/command/suite/system/statistics/object/count/per-volume/record.expected +19 -0
- data/test/command/suite/system/statistics/object/count/per-volume/record.test +23 -0
- data/test/command/suite/system/statistics/object/count/per-volume/schema.catalog.json +40 -0
- data/test/command/suite/system/statistics/object/count/per-volume/schema.expected +19 -0
- data/test/command/suite/system/statistics/object/count/per-volume/schema.test +13 -0
- data/test/command/suite/system/statistics/object/count/record.catalog.json +12 -0
- data/test/command/suite/system/statistics/object/count/record.expected +11 -0
- data/test/command/suite/system/statistics/object/count/record.test +23 -0
- data/test/command/suite/system/statistics/object/count/schema.catalog.json +12 -0
- data/test/command/suite/system/statistics/object/count/schema.expected +11 -0
- data/test/command/suite/system/statistics/object/count/schema.test +13 -0
- data/test/command/suite/system/status.expected +3 -2
- data/test/unit/catalog/test_dataset.rb +4 -1
- data/test/unit/{test_catalog_generator.rb → catalog/test_generator.rb} +2 -2
- data/test/unit/catalog/test_replicas_volume.rb +79 -0
- data/test/unit/catalog/test_single_volume.rb +2 -2
- data/test/unit/catalog/test_slice.rb +33 -1
- data/test/unit/catalog/{test_collection_volume.rb → test_slices_volume.rb} +72 -11
- data/test/unit/catalog/test_version2.rb +3 -0
- data/test/unit/helper/distributed_search_planner_helper.rb +2 -2
- data/test/unit/plugins/catalog/test_fetch.rb +4 -4
- data/test/unit/plugins/crud/test_add.rb +44 -4
- data/test/unit/plugins/groonga/test_column_create.rb +4 -4
- data/test/unit/plugins/groonga/test_column_list.rb +4 -4
- data/test/unit/plugins/groonga/test_column_remove.rb +4 -4
- data/test/unit/plugins/groonga/test_column_rename.rb +4 -4
- data/test/unit/plugins/groonga/test_delete.rb +73 -10
- data/test/unit/plugins/groonga/test_table_create.rb +4 -4
- data/test/unit/plugins/groonga/test_table_list.rb +4 -4
- data/test/unit/plugins/groonga/test_table_remove.rb +4 -4
- data/test/unit/plugins/search/test_handler.rb +4 -4
- data/test/unit/plugins/search/test_planner.rb +4 -2
- data/test/unit/plugins/system/test_status.rb +31 -15
- data/test/unit/plugins/test_watch.rb +16 -16
- data/test/unit/test_address.rb +4 -4
- metadata +134 -35
- data/lib/droonga/catalog/volume_collection.rb +0 -79
- data/lib/droonga/catalog_fetcher.rb +0 -53
- data/lib/droonga/catalog_generator.rb +0 -243
- data/lib/droonga/catalog_loader.rb +0 -56
- data/lib/droonga/command/remote.rb +0 -404
- data/lib/droonga/data_absorber.rb +0 -264
- data/lib/droonga/node_status.rb +0 -71
- data/lib/droonga/serf_downloader.rb +0 -115
- data/test/unit/catalog/test_volume_collection.rb +0 -78
data/install/centos/functions.sh
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2014 Droonga Project
|
|
1
|
+
# Copyright (C) 2014-2015 Droonga Project
|
|
2
2
|
#
|
|
3
3
|
# This library is free software; you can redistribute it and/or
|
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -20,7 +20,7 @@ register_service() {
|
|
|
20
20
|
|
|
21
21
|
#TODO: we should migrate to systemd in near future...
|
|
22
22
|
|
|
23
|
-
curl -o /etc/rc.d/init.d/$NAME $(download_url "install/centos/$NAME")
|
|
23
|
+
curl -s -o /etc/rc.d/init.d/$NAME $(download_url "install/centos/$NAME")
|
|
24
24
|
if [ $? -ne 0 ]; then
|
|
25
25
|
echo "ERROR: Failed to download service script!"
|
|
26
26
|
exit 1
|
data/install/debian/functions.sh
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2014 Droonga Project
|
|
1
|
+
# Copyright (C) 2014-2015 Droonga Project
|
|
2
2
|
#
|
|
3
3
|
# This library is free software; you can redistribute it and/or
|
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -18,7 +18,7 @@ register_service() {
|
|
|
18
18
|
local USER=$2
|
|
19
19
|
local GROUP=$3
|
|
20
20
|
|
|
21
|
-
curl -o /etc/init.d/$NAME $(download_url "install/debian/$NAME")
|
|
21
|
+
curl -s -o /etc/init.d/$NAME $(download_url "install/debian/$NAME")
|
|
22
22
|
if [ $? -ne 0 ]; then
|
|
23
23
|
echo "ERROR: Failed to download service script!"
|
|
24
24
|
exit 1
|
data/lib/droonga/address.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2014 Droonga Project
|
|
1
|
+
# Copyright (C) 2014-2015 Droonga Project
|
|
2
2
|
#
|
|
3
3
|
# This library is free software; you can redistribute it and/or
|
|
4
4
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -13,7 +13,7 @@
|
|
|
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 "
|
|
16
|
+
require "droonga/node_name"
|
|
17
17
|
|
|
18
18
|
module Droonga
|
|
19
19
|
class Address
|
|
@@ -24,49 +24,51 @@ module Droonga
|
|
|
24
24
|
:host => $1,
|
|
25
25
|
:port => $2.to_i,
|
|
26
26
|
:tag => $3,
|
|
27
|
-
:
|
|
27
|
+
:local_name => $4
|
|
28
28
|
}
|
|
29
29
|
new(components)
|
|
30
30
|
else
|
|
31
|
-
format = "${host_name}:${port_number}/${tag}.${
|
|
31
|
+
format = "${host_name}:${port_number}/${tag}.${local_name}"
|
|
32
32
|
message = "volume address must be <#{format}> format: <#{string}>"
|
|
33
33
|
raise ArgumentError, message
|
|
34
34
|
end
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
DEFAULT_HOST.force_encoding("US-ASCII") if DEFAULT_HOST.ascii_only?
|
|
40
|
-
DEFAULT_PORT = 10031
|
|
41
|
-
DEFAULT_TAG = "droonga"
|
|
42
|
-
|
|
43
|
-
attr_reader :host
|
|
44
|
-
attr_reader :port
|
|
45
|
-
attr_reader :tag
|
|
46
|
-
attr_reader :name
|
|
38
|
+
attr_reader :local_name
|
|
47
39
|
def initialize(components={})
|
|
48
|
-
@
|
|
49
|
-
@
|
|
50
|
-
|
|
51
|
-
|
|
40
|
+
@node_name = NodeName.new(components)
|
|
41
|
+
@local_name = components[:local_name]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def host
|
|
45
|
+
@node_name.host
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def port
|
|
49
|
+
@node_name.port
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def tag
|
|
53
|
+
@node_name.tag
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def node
|
|
57
|
+
@node_name.node
|
|
52
58
|
end
|
|
53
59
|
|
|
54
60
|
def to_s
|
|
55
|
-
string = node
|
|
56
|
-
string << ".#{@
|
|
61
|
+
string = @node_name.node
|
|
62
|
+
string << ".#{@local_name}" if @local_name
|
|
57
63
|
string
|
|
58
64
|
end
|
|
59
65
|
|
|
60
66
|
def to_a
|
|
61
|
-
|
|
67
|
+
@node_name.to_a + [@local_name]
|
|
62
68
|
end
|
|
63
69
|
|
|
64
70
|
def ==(other)
|
|
65
71
|
other.is_a?(self.class) and to_a == other.to_a
|
|
66
72
|
end
|
|
67
|
-
|
|
68
|
-
def node
|
|
69
|
-
"#{@host}:#{@port}/#{@tag}"
|
|
70
|
-
end
|
|
71
73
|
end
|
|
72
74
|
end
|
|
@@ -18,11 +18,15 @@
|
|
|
18
18
|
require "coolio"
|
|
19
19
|
|
|
20
20
|
require "droonga/loggable"
|
|
21
|
+
require "droonga/timestamp"
|
|
21
22
|
|
|
22
23
|
module Droonga
|
|
23
24
|
class BufferedTCPSocket < Coolio::TCPSocket
|
|
24
25
|
include Loggable
|
|
25
26
|
|
|
27
|
+
class AlreadyInWritingByOthers < StandardError
|
|
28
|
+
end
|
|
29
|
+
|
|
26
30
|
def initialize(socket, data_directory)
|
|
27
31
|
super(socket)
|
|
28
32
|
@data_directory = data_directory
|
|
@@ -34,7 +38,8 @@ module Droonga
|
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
def write(data)
|
|
37
|
-
chunk = Chunk.new(@data_directory,
|
|
41
|
+
chunk = Chunk.new(:directory => @data_directory,
|
|
42
|
+
:data => data)
|
|
38
43
|
chunk.buffering
|
|
39
44
|
@_write_buffer << chunk
|
|
40
45
|
schedule_write
|
|
@@ -45,19 +50,35 @@ module Droonga
|
|
|
45
50
|
until @_write_buffer.empty?
|
|
46
51
|
chunk = @_write_buffer.shift
|
|
47
52
|
begin
|
|
53
|
+
chunk.writing
|
|
54
|
+
logger.trace("Sending...", :data => chunk.data)
|
|
48
55
|
written_size = @_io.write_nonblock(chunk.data)
|
|
49
56
|
if written_size == chunk.data.bytesize
|
|
50
57
|
chunk.written
|
|
58
|
+
logger.trace("Completely sent.")
|
|
51
59
|
else
|
|
52
60
|
chunk.written_partial(written_size)
|
|
61
|
+
logger.trace("Partially sent. Retry later.",
|
|
62
|
+
:written => written_size,
|
|
63
|
+
:rest => chunk.data.bytesize)
|
|
53
64
|
@_write_buffer.unshift(chunk)
|
|
54
65
|
break
|
|
55
66
|
end
|
|
67
|
+
rescue AlreadyInWritingByOthers
|
|
68
|
+
logger.trace("Chunk is already in sending by another process.")
|
|
56
69
|
rescue Errno::EINTR
|
|
57
70
|
@_write_buffer.unshift(chunk)
|
|
71
|
+
chunk.failed
|
|
72
|
+
logger.trace("Failed to send chunk. Retry later.",
|
|
73
|
+
:chunk => chunk,
|
|
74
|
+
:errpr => "Errno::EINTR")
|
|
58
75
|
return
|
|
59
|
-
rescue SystemCallError, IOError, SocketError
|
|
76
|
+
rescue SystemCallError, IOError, SocketError => exception
|
|
60
77
|
@_write_buffer.unshift(chunk)
|
|
78
|
+
chunk.failed
|
|
79
|
+
logger.trace("Failed to send chunk. Retry later.",
|
|
80
|
+
:chunk => chunk,
|
|
81
|
+
:exception => exception)
|
|
61
82
|
return close
|
|
62
83
|
end
|
|
63
84
|
end
|
|
@@ -108,24 +129,30 @@ module Droonga
|
|
|
108
129
|
|
|
109
130
|
class Chunk
|
|
110
131
|
SUFFIX = ".chunk"
|
|
132
|
+
WRITING_SUFFIX = ".writing"
|
|
111
133
|
|
|
112
134
|
class << self
|
|
113
135
|
def load(path)
|
|
114
136
|
data_directory = path.dirname
|
|
115
|
-
time_stamp1, time_stamp2, revision, = path.basename.to_s.split(".",
|
|
137
|
+
time_stamp1, time_stamp2, uniqueness, revision, = path.basename.to_s.split(".", 5)
|
|
116
138
|
data = path.open("rb") {|file| file.read}
|
|
117
139
|
time_stamp = Time.iso8601("#{time_stamp1}.#{time_stamp2}")
|
|
118
140
|
revision = Integer(revision)
|
|
119
|
-
new(data_directory,
|
|
141
|
+
new(:directory => data_directory,
|
|
142
|
+
:data => data,
|
|
143
|
+
:time_stamp => time_stamp,
|
|
144
|
+
:uniqueness => uniqueness,
|
|
145
|
+
:revision => revision)
|
|
120
146
|
end
|
|
121
147
|
end
|
|
122
148
|
|
|
123
149
|
attr_reader :data, :time_stamp
|
|
124
|
-
def initialize(
|
|
125
|
-
@data_directory =
|
|
126
|
-
@data = data
|
|
127
|
-
@time_stamp = time_stamp.
|
|
128
|
-
@
|
|
150
|
+
def initialize(params)
|
|
151
|
+
@data_directory = params[:directory]
|
|
152
|
+
@data = params[:data]
|
|
153
|
+
@time_stamp = params[:time_stamp] || Time.now
|
|
154
|
+
@uniqueness = params[:uniqueness]
|
|
155
|
+
@revision = params[:revision] || 0
|
|
129
156
|
end
|
|
130
157
|
|
|
131
158
|
def buffering
|
|
@@ -134,8 +161,23 @@ module Droonga
|
|
|
134
161
|
end
|
|
135
162
|
end
|
|
136
163
|
|
|
164
|
+
def writing
|
|
165
|
+
raise AlreadyInWritingByOthers.new if writing?
|
|
166
|
+
FileUtils.mv(path.to_s, writing_path.to_s)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def writing?
|
|
170
|
+
not path.exist?
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def failed
|
|
174
|
+
return unless writing?
|
|
175
|
+
FileUtils.mv(writing_path.to_s, path.to_s)
|
|
176
|
+
end
|
|
177
|
+
|
|
137
178
|
def written
|
|
138
179
|
FileUtils.rm_f(path.to_s)
|
|
180
|
+
FileUtils.rm_f(writing_path.to_s)
|
|
139
181
|
end
|
|
140
182
|
|
|
141
183
|
def written_partial(size)
|
|
@@ -147,7 +189,20 @@ module Droonga
|
|
|
147
189
|
|
|
148
190
|
private
|
|
149
191
|
def path
|
|
150
|
-
@
|
|
192
|
+
@path ||= create_chunk_file_path
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def writing_path
|
|
196
|
+
@writing_path ||= Pathname("#{path.to_s}#{WRITING_SUFFIX}")
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def create_chunk_file_path
|
|
200
|
+
basename = Timestamp.stringify(@time_stamp)
|
|
201
|
+
if @uniqueness
|
|
202
|
+
@data_directory + "#{basename}.#{@uniqueness}.#{@revision}#{SUFFIX}"
|
|
203
|
+
else
|
|
204
|
+
Path.unique_file_path(@data_directory, basename, "#{@revision}#{SUFFIX}")
|
|
205
|
+
end
|
|
151
206
|
end
|
|
152
207
|
end
|
|
153
208
|
end
|
data/lib/droonga/catalog/base.rb
CHANGED
|
@@ -24,10 +24,10 @@ module Droonga
|
|
|
24
24
|
module Catalog
|
|
25
25
|
class Base
|
|
26
26
|
attr_reader :path, :base_path
|
|
27
|
-
def initialize(
|
|
28
|
-
@
|
|
29
|
-
@path = path
|
|
30
|
-
@base_path = File.dirname(path)
|
|
27
|
+
def initialize(raw, path)
|
|
28
|
+
@raw = raw
|
|
29
|
+
@path = path || "/tmp/temporary-catalog.json"
|
|
30
|
+
@base_path = File.dirname(@path)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def have_dataset?(name)
|
|
@@ -44,8 +44,11 @@ module Droonga
|
|
|
44
44
|
|
|
45
45
|
private
|
|
46
46
|
def calculate_cluster_id
|
|
47
|
-
raw_id =
|
|
48
|
-
|
|
47
|
+
raw_id = []
|
|
48
|
+
datasets.each do |name, dataset|
|
|
49
|
+
raw_id << "#{name}-#{dataset.all_nodes.sort.join(",")}"
|
|
50
|
+
end
|
|
51
|
+
Digest::SHA1.hexdigest(raw_id.sort.join("|"))
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
def migrate_database_location(current_db_path, device, name)
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
|
|
16
16
|
require "droonga/catalog/schema"
|
|
17
17
|
require "droonga/catalog/volume"
|
|
18
|
-
require "droonga/catalog/volume_collection"
|
|
19
18
|
|
|
20
19
|
module Droonga
|
|
21
20
|
module Catalog
|
|
@@ -24,80 +23,57 @@ module Droonga
|
|
|
24
23
|
|
|
25
24
|
attr_reader :name
|
|
26
25
|
|
|
27
|
-
def initialize(name,
|
|
26
|
+
def initialize(name, raw)
|
|
28
27
|
@name = name
|
|
29
|
-
@
|
|
28
|
+
@raw = raw
|
|
30
29
|
@schema = nil
|
|
31
30
|
end
|
|
32
31
|
|
|
33
32
|
# provided for compatibility
|
|
34
33
|
def [](key)
|
|
35
|
-
@
|
|
34
|
+
@raw[key]
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
# provided for compatibility
|
|
39
38
|
def []=(key, value)
|
|
40
|
-
@
|
|
39
|
+
@raw[key] = value
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
def schema
|
|
44
|
-
@schema ||= Schema.new(@name, @
|
|
43
|
+
@schema ||= Schema.new(@name, @raw["schema"])
|
|
45
44
|
end
|
|
46
45
|
|
|
47
46
|
def plugins
|
|
48
|
-
@
|
|
47
|
+
@raw["plugins"] || []
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
def fact
|
|
52
|
-
@
|
|
51
|
+
@raw["fact"]
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def n_workers
|
|
56
|
-
@
|
|
55
|
+
@raw["nWorkers"] || 0
|
|
57
56
|
end
|
|
58
57
|
|
|
58
|
+
#XXX Currently, dataset has a property named "replicas" so
|
|
59
|
+
# can be parsed as a ReplicasVolume.
|
|
60
|
+
# We must introduce a new property "volume" to provide
|
|
61
|
+
# ReplicasVolume safely.
|
|
59
62
|
def replicas
|
|
60
|
-
@replicas ||=
|
|
63
|
+
@replicas ||= ReplicasVolume.new(self, @raw)
|
|
61
64
|
end
|
|
62
65
|
|
|
63
66
|
def all_nodes
|
|
64
67
|
@all_nodes ||= replicas.all_nodes
|
|
65
68
|
end
|
|
66
69
|
|
|
67
|
-
def compute_routes(message,
|
|
68
|
-
|
|
69
|
-
case message["type"]
|
|
70
|
-
when "broadcast"
|
|
71
|
-
volumes = replicas.select(message["replica"].to_sym, live_nodes)
|
|
72
|
-
volumes.each do |volume|
|
|
73
|
-
slices = volume.select_slices
|
|
74
|
-
slices.each do |slice|
|
|
75
|
-
routes << slice.volume.address.to_s
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
when "scatter"
|
|
79
|
-
volumes = replicas.select(message["replica"].to_sym, live_nodes)
|
|
80
|
-
volumes.each do |volume|
|
|
81
|
-
slice = volume.choose_slice(message["record"])
|
|
82
|
-
routes << slice.volume.address.to_s
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
routes
|
|
70
|
+
def compute_routes(message, active_nodes)
|
|
71
|
+
@replicas.compute_routes(message, active_nodes)
|
|
86
72
|
end
|
|
87
73
|
|
|
88
|
-
def
|
|
74
|
+
def sliced?
|
|
89
75
|
# TODO: Support slice key
|
|
90
|
-
replicas.
|
|
91
|
-
volume.is_a?(SingleVolume) or
|
|
92
|
-
volume.slices.size == 1
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
private
|
|
97
|
-
def create_volumes(raw_volumes)
|
|
98
|
-
raw_volumes.collect do |raw_volume|
|
|
99
|
-
Volume.create(self, raw_volume)
|
|
100
|
-
end
|
|
76
|
+
@replicas.sliced?
|
|
101
77
|
end
|
|
102
78
|
end
|
|
103
79
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
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 "socket"
|
|
17
|
+
|
|
18
|
+
require "droonga/client"
|
|
19
|
+
|
|
20
|
+
require "droonga/node_name"
|
|
21
|
+
require "droonga/catalog/dataset"
|
|
22
|
+
|
|
23
|
+
module Droonga
|
|
24
|
+
module Catalog
|
|
25
|
+
class Fetcher
|
|
26
|
+
class EmptyResponse < StandardError
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class EmptyCatalog < StandardError
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def initialize(client_options)
|
|
33
|
+
@client_options = default_options.merge(client_options)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def fetch(options={})
|
|
37
|
+
message = {
|
|
38
|
+
"dataset" => options[:dataset] || Catalog::Dataset::DEFAULT_NAME,
|
|
39
|
+
"type" => "catalog.fetch"
|
|
40
|
+
}
|
|
41
|
+
response = nil
|
|
42
|
+
Droonga::Client.open(@client_options) do |client|
|
|
43
|
+
response = client.request(message)
|
|
44
|
+
end
|
|
45
|
+
raise EmptyResponse.new unless response
|
|
46
|
+
raise EmptyCatalog.new unless response["body"]
|
|
47
|
+
response["body"]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
def default_options
|
|
52
|
+
{
|
|
53
|
+
:host => "127.0.0.1",
|
|
54
|
+
:port => NodeName::DEFAULT_PORT,
|
|
55
|
+
:tag => NodeName::DEFAULT_TAG,
|
|
56
|
+
:protocol => :droonga,
|
|
57
|
+
:timeout => 1,
|
|
58
|
+
:receiver_host => Socket.gethostname,
|
|
59
|
+
:receiver_port => 0,
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|