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
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Copyright (C) 2015 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 "groonga"
|
|
17
|
+
|
|
18
|
+
module Droonga
|
|
19
|
+
module DatabaseScanner
|
|
20
|
+
def n_tables
|
|
21
|
+
n_tables = 0
|
|
22
|
+
each_table do |table|
|
|
23
|
+
n_tables += 1
|
|
24
|
+
end
|
|
25
|
+
n_tables
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def n_columns
|
|
29
|
+
n_columns = 0
|
|
30
|
+
each_table do |table|
|
|
31
|
+
n_columns += table.columns.size
|
|
32
|
+
end
|
|
33
|
+
n_columns
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def n_records
|
|
37
|
+
n_records = 0
|
|
38
|
+
each_table do |table|
|
|
39
|
+
unless index_only_table?(table)
|
|
40
|
+
n_records += table.size
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
n_records
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def total_n_objects
|
|
47
|
+
n_tables = 0
|
|
48
|
+
n_columns = 0
|
|
49
|
+
n_records = 0
|
|
50
|
+
each_table do |table|
|
|
51
|
+
n_tables += 1
|
|
52
|
+
n_columns += table.columns.size
|
|
53
|
+
unless index_only_table?(table)
|
|
54
|
+
n_records += table.size
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
n_tables + n_columns + n_records
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def each_table(&block)
|
|
61
|
+
options = {
|
|
62
|
+
:ignore_missing_object => true,
|
|
63
|
+
:order_by => :key,
|
|
64
|
+
}
|
|
65
|
+
reference_tables = []
|
|
66
|
+
@context.database.each(options) do |object|
|
|
67
|
+
next unless table?(object)
|
|
68
|
+
if reference_table?(object)
|
|
69
|
+
reference_tables << object
|
|
70
|
+
next
|
|
71
|
+
end
|
|
72
|
+
yield(object)
|
|
73
|
+
end
|
|
74
|
+
reference_tables.each do |reference_table|
|
|
75
|
+
yield(object)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def table?(object)
|
|
80
|
+
object.is_a?(::Groonga::Table)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def reference_table?(table)
|
|
84
|
+
table.support_key? and table?(table.domain)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def index_only_table?(table)
|
|
88
|
+
return false if table.columns.empty?
|
|
89
|
+
table.columns.all? do |column|
|
|
90
|
+
index_column?(column)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def index_column?(column)
|
|
95
|
+
column.is_a?(::Groonga::IndexColumn)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def each_index_columns(&block)
|
|
99
|
+
each_table do |table|
|
|
100
|
+
table.columns.each do |column|
|
|
101
|
+
yield(column) if index_column?(column)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C)
|
|
1
|
+
# Copyright (C) 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,36 +13,23 @@
|
|
|
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 "pathname"
|
|
17
|
-
require "json"
|
|
18
|
-
|
|
19
16
|
module Droonga
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@path = path
|
|
23
|
-
end
|
|
17
|
+
module Deferrable
|
|
18
|
+
attr_writer :on_ready, :on_failure
|
|
24
19
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
20
|
+
def wait_until_ready(target)
|
|
21
|
+
target.on_ready = lambda do
|
|
22
|
+
on_ready
|
|
23
|
+
end
|
|
28
24
|
end
|
|
29
25
|
|
|
30
26
|
private
|
|
31
|
-
def
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
contents = @path.read
|
|
35
|
-
return default_list if contents.empty?
|
|
36
|
-
|
|
37
|
-
begin
|
|
38
|
-
JSON.parse(contents)
|
|
39
|
-
rescue JSON::ParserError
|
|
40
|
-
default_list
|
|
41
|
-
end
|
|
27
|
+
def on_ready
|
|
28
|
+
@on_ready.call if @on_ready
|
|
42
29
|
end
|
|
43
30
|
|
|
44
|
-
def
|
|
45
|
-
|
|
31
|
+
def on_failure
|
|
32
|
+
@on_failure.call if @on_failure
|
|
46
33
|
end
|
|
47
34
|
end
|
|
48
35
|
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright (C) 2015 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
|
+
module Droonga
|
|
17
|
+
module Differ
|
|
18
|
+
class << self
|
|
19
|
+
def diff(a, b)
|
|
20
|
+
unless a.class == b.class
|
|
21
|
+
return "#{a.inspect} <=> #{b.inspect}"
|
|
22
|
+
end
|
|
23
|
+
case a
|
|
24
|
+
when Hash
|
|
25
|
+
diff_hashes(a, b)
|
|
26
|
+
when Array
|
|
27
|
+
diff_arrays(a, b)
|
|
28
|
+
else
|
|
29
|
+
if a == b
|
|
30
|
+
nil
|
|
31
|
+
else
|
|
32
|
+
"#{a.inspect} <=> #{b.inspect}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def diff_hashes(a, b)
|
|
38
|
+
difference = {}
|
|
39
|
+
(a.keys + b.keys).uniq.each do |key|
|
|
40
|
+
unless a[key] == b[key]
|
|
41
|
+
difference[key] = diff(a[key], b[key])
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
difference
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def diff_arrays(a, b)
|
|
48
|
+
difference = {}
|
|
49
|
+
[a.size, b.size].max.times do |index|
|
|
50
|
+
unless a[index] == b[index]
|
|
51
|
+
difference[index] = diff(a[index], b[index])
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
difference
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/droonga/dispatcher.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (C) 2013-
|
|
1
|
+
# Copyright (C) 2013-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
|
|
@@ -23,6 +23,7 @@ require "droonga/farm"
|
|
|
23
23
|
require "droonga/session"
|
|
24
24
|
require "droonga/error_messages"
|
|
25
25
|
require "droonga/distributor"
|
|
26
|
+
require "droonga/node_role"
|
|
26
27
|
|
|
27
28
|
module Droonga
|
|
28
29
|
class Dispatcher
|
|
@@ -46,30 +47,32 @@ module Droonga
|
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
49
|
|
|
49
|
-
attr_reader :engine_state
|
|
50
|
+
attr_reader :engine_state, :cluster
|
|
50
51
|
|
|
51
|
-
def initialize(engine_state, catalog)
|
|
52
|
+
def initialize(engine_state, cluster, catalog)
|
|
52
53
|
@engine_state = engine_state
|
|
54
|
+
@cluster = cluster
|
|
53
55
|
@forwarder = @engine_state.forwarder
|
|
54
56
|
@replier = @engine_state.replier
|
|
55
57
|
@catalog = catalog
|
|
56
58
|
@adapter_runners = create_adapter_runners
|
|
57
59
|
@farm = Farm.new(@engine_state.name, @catalog, @engine_state.loop,
|
|
58
60
|
:engine_state => @engine_state,
|
|
61
|
+
:cluster => @cluster,
|
|
59
62
|
:dispatcher => self,
|
|
60
|
-
:forwarder => @forwarder
|
|
63
|
+
:forwarder => @forwarder,
|
|
64
|
+
:internal_connection_lifetime =>
|
|
65
|
+
@engine_state.internal_connection_lifetime)
|
|
66
|
+
@engine_state.wait_until_ready(@farm)
|
|
61
67
|
@collector_runners = create_collector_runners
|
|
62
68
|
@step_runners = create_step_runners
|
|
63
69
|
end
|
|
64
70
|
|
|
65
71
|
def start
|
|
66
|
-
@farm.on_ready = lambda do
|
|
67
|
-
@engine_state.on_ready
|
|
68
|
-
end
|
|
69
72
|
@farm.start
|
|
70
73
|
end
|
|
71
74
|
|
|
72
|
-
def stop_gracefully(&
|
|
75
|
+
def stop_gracefully(&block)
|
|
73
76
|
logger.trace("stop_gracefully: start")
|
|
74
77
|
@collector_runners.each_value do |collector_runner|
|
|
75
78
|
collector_runner.shutdown
|
|
@@ -77,8 +80,10 @@ module Droonga
|
|
|
77
80
|
@adapter_runners.each_value do |adapter_runner|
|
|
78
81
|
adapter_runner.shutdown
|
|
79
82
|
end
|
|
80
|
-
@farm.stop_gracefully
|
|
81
|
-
|
|
83
|
+
@farm.stop_gracefully do
|
|
84
|
+
yield
|
|
85
|
+
logger.trace("stop_gracefully: done")
|
|
86
|
+
end
|
|
82
87
|
end
|
|
83
88
|
|
|
84
89
|
def stop_immediately
|
|
@@ -89,11 +94,16 @@ module Droonga
|
|
|
89
94
|
@adapter_runners.each_value do |adapter_runner|
|
|
90
95
|
adapter_runner.shutdown
|
|
91
96
|
end
|
|
92
|
-
@farm.
|
|
97
|
+
@farm.stop_immediately
|
|
93
98
|
logger.trace("stop_immediately: done")
|
|
94
99
|
end
|
|
95
100
|
|
|
101
|
+
def refresh_node_reference
|
|
102
|
+
@farm.refresh_node_reference
|
|
103
|
+
end
|
|
104
|
+
|
|
96
105
|
def process_message(message)
|
|
106
|
+
logger.trace("process_message: start", :message => message)
|
|
97
107
|
@message = message
|
|
98
108
|
if message["type"] == "dispatcher"
|
|
99
109
|
process_internal_message(message["body"])
|
|
@@ -111,11 +121,16 @@ module Droonga
|
|
|
111
121
|
"body" => formatted_error.response_body)
|
|
112
122
|
end
|
|
113
123
|
end
|
|
124
|
+
logger.trace("process_message: done")
|
|
114
125
|
end
|
|
115
126
|
|
|
116
127
|
def forward(message, destination)
|
|
117
128
|
logger.trace("forward start")
|
|
118
|
-
|
|
129
|
+
if local_route?(destination) or direct_route?(destination)
|
|
130
|
+
@forwarder.forward(message, destination)
|
|
131
|
+
else
|
|
132
|
+
@cluster.forward(message, destination)
|
|
133
|
+
end
|
|
119
134
|
logger.trace("forward done")
|
|
120
135
|
end
|
|
121
136
|
|
|
@@ -153,82 +168,147 @@ module Droonga
|
|
|
153
168
|
end
|
|
154
169
|
|
|
155
170
|
def process_internal_message(message)
|
|
171
|
+
logger.trace("process_internal_message: start", :message => message)
|
|
156
172
|
id = message["id"]
|
|
157
173
|
session = @engine_state.find_session(id)
|
|
158
174
|
if session
|
|
159
175
|
session.receive(message["input"], message["value"])
|
|
160
176
|
else
|
|
177
|
+
logger.trace("process_internal_message: no session")
|
|
161
178
|
steps = message["steps"]
|
|
162
179
|
if steps
|
|
163
|
-
session_planner = SessionPlanner.new(@engine_state, steps)
|
|
180
|
+
session_planner = SessionPlanner.new(@engine_state, @cluster, steps)
|
|
164
181
|
dataset = message["dataset"] || @message["dataset"]
|
|
165
182
|
collector_runner = @collector_runners[dataset]
|
|
166
183
|
session = session_planner.create_session(id, self, collector_runner)
|
|
167
|
-
|
|
184
|
+
if session.need_result?
|
|
185
|
+
timeout = message["timeout"] ||
|
|
186
|
+
@engine_state.internal_connection_lifetime
|
|
187
|
+
@engine_state.register_session(id, session,
|
|
188
|
+
:timeout => timeout)
|
|
189
|
+
session.start
|
|
190
|
+
logger.trace("process_internal_message: waiting for results")
|
|
191
|
+
else
|
|
192
|
+
session.start
|
|
193
|
+
session.finish
|
|
194
|
+
session = nil
|
|
195
|
+
logger.trace("process_internal_message: no need to wait for results")
|
|
196
|
+
end
|
|
168
197
|
else
|
|
169
|
-
logger.error("no steps error: id
|
|
198
|
+
logger.error("no steps error", :id => id, :message => message)
|
|
170
199
|
return
|
|
171
200
|
#todo: take cases receiving result before its query into account
|
|
172
201
|
end
|
|
173
|
-
session.start
|
|
174
202
|
end
|
|
175
|
-
@engine_state.unregister_session(id) if session.done?
|
|
203
|
+
@engine_state.unregister_session(id) if session and session.done?
|
|
204
|
+
logger.trace("process_internal_message: done")
|
|
176
205
|
end
|
|
177
206
|
|
|
178
207
|
def dispatch(message, destination)
|
|
179
|
-
|
|
208
|
+
logger.trace("dispatch: start", :message => message, :destination => destination)
|
|
209
|
+
if local_route?(destination)
|
|
180
210
|
process_internal_message(message)
|
|
181
211
|
else
|
|
182
|
-
@
|
|
183
|
-
|
|
184
|
-
|
|
212
|
+
forward_message = @message.merge("body" => message)
|
|
213
|
+
forward_destination = {
|
|
214
|
+
"type" => "dispatcher",
|
|
215
|
+
"to" => destination,
|
|
216
|
+
}
|
|
217
|
+
if direct_route?(forward_destination)
|
|
218
|
+
@forwarder.forward(forward_message, forward_destination)
|
|
219
|
+
else
|
|
220
|
+
@cluster.forward(forward_message, forward_destination)
|
|
221
|
+
end
|
|
185
222
|
end
|
|
223
|
+
logger.trace("dispatch: done")
|
|
186
224
|
end
|
|
187
225
|
|
|
188
226
|
def dispatch_steps(steps)
|
|
227
|
+
logger.trace("dispatch_steps: start", :steps => steps)
|
|
189
228
|
id = @engine_state.generate_id
|
|
190
229
|
|
|
191
230
|
destinations = []
|
|
231
|
+
timeout = nil
|
|
192
232
|
steps.each do |step|
|
|
233
|
+
calculated_timeout = timeout_from_step(step)
|
|
234
|
+
if calculated_timeout
|
|
235
|
+
timeout = calculated_timeout
|
|
236
|
+
end
|
|
237
|
+
|
|
193
238
|
dataset = @catalog.dataset(step["dataset"])
|
|
194
239
|
if dataset
|
|
195
|
-
|
|
196
|
-
|
|
240
|
+
if write_step?(step)
|
|
241
|
+
step["write"] = true
|
|
242
|
+
target_nodes = @cluster.writable_nodes
|
|
243
|
+
if target_nodes.empty?
|
|
244
|
+
logger.error("there is no node to dispath a write step!",
|
|
245
|
+
:my_role => NodeRole.mine,
|
|
246
|
+
:all_nodes => @cluster.engine_nodes.collect(&:to_json),
|
|
247
|
+
:step => step)
|
|
248
|
+
end
|
|
249
|
+
else
|
|
250
|
+
target_nodes = @cluster.readable_nodes
|
|
251
|
+
if target_nodes.empty?
|
|
252
|
+
logger.error("there is no node to dispath a read step!",
|
|
253
|
+
:my_role => NodeRole.mine,
|
|
254
|
+
:all_nodes => @cluster.engine_nodes.collect(&:to_json),
|
|
255
|
+
:step => step)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
routes = dataset.compute_routes(step, target_nodes)
|
|
259
|
+
step["routes"] = routes.collect do |route|
|
|
260
|
+
internal_route(route)
|
|
261
|
+
end
|
|
197
262
|
else
|
|
198
263
|
step["routes"] ||= [id]
|
|
199
264
|
end
|
|
265
|
+
|
|
200
266
|
destinations += step["routes"].collect do |route|
|
|
201
|
-
|
|
267
|
+
internal_farm_path(route)
|
|
202
268
|
end
|
|
203
269
|
end
|
|
204
270
|
|
|
205
|
-
dispatch_message = {
|
|
271
|
+
dispatch_message = {
|
|
272
|
+
"id" => id,
|
|
273
|
+
"steps" => steps,
|
|
274
|
+
"timeout" => timeout,
|
|
275
|
+
}
|
|
206
276
|
destinations.uniq.each do |destination|
|
|
207
277
|
dispatch(dispatch_message, destination)
|
|
208
278
|
end
|
|
279
|
+
|
|
280
|
+
logger.trace("dispatch_steps: done")
|
|
209
281
|
end
|
|
210
282
|
|
|
211
283
|
def process_local_message(local_message)
|
|
284
|
+
logger.trace("process_local_message: start", :steps => local_message)
|
|
212
285
|
task = local_message["task"]
|
|
213
286
|
slice_name = task["route"]
|
|
287
|
+
slice_name = public_route(slice_name)
|
|
214
288
|
step = task["step"]
|
|
215
289
|
command = step["command"]
|
|
216
290
|
descendants = {}
|
|
217
291
|
step["descendants"].each do |name, routes|
|
|
218
292
|
descendants[name] = routes.collect do |route|
|
|
219
|
-
|
|
293
|
+
internal_farm_path(route)
|
|
220
294
|
end
|
|
221
295
|
end
|
|
222
296
|
local_message["descendants"] = descendants
|
|
223
297
|
farm_message = @message.merge("body" => local_message,
|
|
224
298
|
"type" => command)
|
|
225
299
|
@farm.process(slice_name, farm_message)
|
|
300
|
+
logger.trace("process_local_message: done")
|
|
226
301
|
end
|
|
227
302
|
|
|
228
|
-
def
|
|
303
|
+
def local_route?(route)
|
|
229
304
|
@engine_state.local_route?(route)
|
|
230
305
|
end
|
|
231
306
|
|
|
307
|
+
def direct_route?(route)
|
|
308
|
+
receiver = route["to"]
|
|
309
|
+
not @cluster.engine_node_names.include?(receiver)
|
|
310
|
+
end
|
|
311
|
+
|
|
232
312
|
def write_step?(step)
|
|
233
313
|
return false unless step["dataset"]
|
|
234
314
|
|
|
@@ -241,12 +321,46 @@ module Droonga
|
|
|
241
321
|
step_definition.write?
|
|
242
322
|
end
|
|
243
323
|
|
|
324
|
+
def timeout_from_step(step)
|
|
325
|
+
return nil unless step["dataset"]
|
|
326
|
+
|
|
327
|
+
step_runner = @step_runners[step["dataset"]]
|
|
328
|
+
return nil unless step_runner
|
|
329
|
+
|
|
330
|
+
step_definition = step_runner.find(step["command"])
|
|
331
|
+
return nil unless step_definition
|
|
332
|
+
|
|
333
|
+
step_definition.timeout_for_step(step)
|
|
334
|
+
end
|
|
335
|
+
|
|
244
336
|
private
|
|
245
|
-
def
|
|
246
|
-
@engine_state.
|
|
337
|
+
def internal_route(route)
|
|
338
|
+
@engine_state.internal_route(route)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def public_route(route)
|
|
342
|
+
@engine_state.public_route(route)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def internal_farm_path(route)
|
|
346
|
+
@engine_state.internal_farm_path(route)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def public_farm_path(route)
|
|
350
|
+
@engine_state.public_farm_path(route)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def acceptable_role?(message)
|
|
354
|
+
return true unless message["targetRole"]
|
|
355
|
+
role = message["targetRole"].downcase
|
|
356
|
+
role == NodeRole::ANY or role == NodeRole.mine
|
|
247
357
|
end
|
|
248
358
|
|
|
249
359
|
def process_input_message(message)
|
|
360
|
+
unless acceptable_role?(message)
|
|
361
|
+
@cluster.bounce(message)
|
|
362
|
+
return
|
|
363
|
+
end
|
|
250
364
|
dataset = message["dataset"]
|
|
251
365
|
adapter_runner = @adapter_runners[dataset]
|
|
252
366
|
adapted_message = adapter_runner.adapt_input(message)
|
|
@@ -255,6 +369,7 @@ module Droonga
|
|
|
255
369
|
distributor = Distributor.new(self, plan)
|
|
256
370
|
distributor.distribute
|
|
257
371
|
rescue Droonga::UnsupportedMessageError => error
|
|
372
|
+
logger.trace("process_input_message: rescue", :error => error)
|
|
258
373
|
target_message = error.message
|
|
259
374
|
raise UnknownType.new(target_message["type"], target_message["dataset"])
|
|
260
375
|
end
|
|
@@ -302,8 +417,9 @@ module Droonga
|
|
|
302
417
|
class SessionPlanner
|
|
303
418
|
attr_reader :steps
|
|
304
419
|
|
|
305
|
-
def initialize(engine_state, steps)
|
|
420
|
+
def initialize(engine_state, cluster, steps)
|
|
306
421
|
@engine_state = engine_state
|
|
422
|
+
@cluster = cluster
|
|
307
423
|
@steps = steps
|
|
308
424
|
end
|
|
309
425
|
|
|
@@ -345,14 +461,21 @@ module Droonga
|
|
|
345
461
|
(step["outputs"] || []).each do |output|
|
|
346
462
|
descendants[output] = []
|
|
347
463
|
@descendants[output].each do |index|
|
|
348
|
-
|
|
349
|
-
@steps[index]["n_of_expects"] +=
|
|
464
|
+
responsive_routes = select_responsive_routes(step["routes"])
|
|
465
|
+
@steps[index]["n_of_expects"] += responsive_routes.size
|
|
350
466
|
descendants[output].concat(@steps[index]["routes"])
|
|
351
467
|
end
|
|
352
468
|
end
|
|
353
469
|
step["descendants"] = descendants
|
|
354
470
|
end
|
|
355
471
|
end
|
|
472
|
+
|
|
473
|
+
def select_responsive_routes(routes)
|
|
474
|
+
selected_nodes = @cluster.readable_nodes
|
|
475
|
+
routes.select do |route|
|
|
476
|
+
selected_nodes.include?(@engine_state.public_farm_path(route))
|
|
477
|
+
end
|
|
478
|
+
end
|
|
356
479
|
end
|
|
357
480
|
end
|
|
358
481
|
end
|