droonga-engine 1.0.4 → 1.0.5
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/.gitignore +3 -2
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/Rakefile +1 -1
- data/benchmark/benchmark.rb +1 -1
- data/benchmark/utils.rb +1 -1
- data/benchmark/watch/benchmark-notify.rb +1 -1
- data/benchmark/watch/benchmark-publish.rb +1 -1
- data/benchmark/watch/benchmark-scan.rb +1 -1
- data/bin/droonga-engine +1 -1
- data/bin/droonga-engine-absorb-data +48 -8
- data/bin/droonga-engine-catalog-generate +1 -1
- data/bin/droonga-engine-catalog-modify +1 -1
- data/bin/droonga-engine-data-publisher +66 -0
- data/bin/droonga-engine-join +72 -17
- data/bin/droonga-engine-serf-event-handler +1 -1
- data/bin/droonga-engine-service +1 -1
- data/bin/droonga-engine-unjoin +11 -4
- data/bin/droonga-engine-worker +20 -0
- data/doc/text/news.md +8 -0
- data/droonga-engine.gemspec +3 -3
- data/lib/droonga/adapter.rb +1 -1
- data/lib/droonga/adapter_runner.rb +1 -1
- data/lib/droonga/address.rb +69 -0
- data/lib/droonga/buffered_tcp_socket.rb +44 -22
- data/lib/droonga/catalog/base.rb +1 -1
- data/lib/droonga/catalog/collection_volume.rb +1 -1
- data/lib/droonga/catalog/dataset.rb +8 -8
- data/lib/droonga/catalog/errors.rb +1 -1
- data/lib/droonga/catalog/schema.rb +1 -1
- data/lib/droonga/catalog/single_volume.rb +6 -8
- data/lib/droonga/catalog/slice.rb +1 -1
- data/lib/droonga/catalog/version1.rb +2 -2
- data/lib/droonga/catalog/version2.rb +6 -6
- data/lib/droonga/catalog/version2_validator.rb +1 -1
- data/lib/droonga/catalog/volume.rb +1 -1
- data/lib/droonga/catalog/volume_collection.rb +2 -2
- data/lib/droonga/catalog_generator.rb +49 -53
- data/lib/droonga/catalog_loader.rb +1 -1
- data/lib/droonga/collector.rb +1 -1
- data/lib/droonga/collector_message.rb +1 -1
- data/lib/droonga/collector_runner.rb +1 -1
- data/lib/droonga/collectors/and.rb +1 -1
- data/lib/droonga/collectors/or.rb +1 -1
- data/lib/droonga/collectors/sum.rb +1 -1
- data/lib/droonga/collectors.rb +1 -1
- data/lib/droonga/command/droonga_engine.rb +103 -55
- data/lib/droonga/command/droonga_engine_service.rb +22 -67
- data/lib/droonga/command/droonga_engine_worker.rb +232 -0
- data/lib/droonga/command/serf_event_handler.rb +126 -46
- data/lib/droonga/data_absorber.rb +32 -14
- data/lib/droonga/dispatcher.rb +15 -11
- data/lib/droonga/distributed_command_planner.rb +1 -1
- data/lib/droonga/distributor.rb +1 -1
- data/lib/droonga/engine/version.rb +2 -2
- data/lib/droonga/engine.rb +8 -3
- data/lib/droonga/engine_state.rb +15 -6
- data/lib/droonga/error.rb +1 -1
- data/lib/droonga/error_messages.rb +1 -1
- data/lib/droonga/event_loop.rb +1 -1
- data/lib/droonga/farm.rb +9 -1
- data/lib/droonga/file_observer.rb +1 -1
- data/lib/droonga/fluent_message_receiver.rb +11 -5
- data/lib/droonga/fluent_message_sender.rb +14 -17
- data/lib/droonga/forwarder.rb +23 -13
- data/lib/droonga/handler.rb +1 -1
- data/lib/droonga/handler_message.rb +1 -1
- data/lib/droonga/handler_messenger.rb +2 -2
- data/lib/droonga/handler_runner.rb +2 -2
- data/lib/droonga/input_message.rb +1 -1
- data/lib/droonga/internal_fluent_message_receiver.rb +3 -2
- data/lib/droonga/job_protocol.rb +1 -1
- data/lib/droonga/job_pusher.rb +1 -1
- data/lib/droonga/job_receiver.rb +1 -1
- data/lib/droonga/line_buffer.rb +1 -1
- data/lib/droonga/live_nodes_list_loader.rb +1 -1
- data/lib/droonga/loggable.rb +1 -1
- data/lib/droonga/logger.rb +3 -3
- data/lib/droonga/message_matcher.rb +1 -1
- data/lib/droonga/output_message.rb +1 -1
- data/lib/droonga/path.rb +5 -1
- data/lib/droonga/planner.rb +1 -1
- data/lib/droonga/pluggable.rb +1 -1
- data/lib/droonga/plugin/metadata/adapter_input_message.rb +1 -1
- data/lib/droonga/plugin/metadata/adapter_output_message.rb +1 -1
- data/lib/droonga/plugin/metadata/collector_message.rb +1 -1
- data/lib/droonga/plugin/metadata/handler_action.rb +1 -1
- data/lib/droonga/plugin/metadata/input_message.rb +1 -1
- data/lib/droonga/plugin.rb +2 -1
- data/lib/droonga/plugin_loader.rb +1 -1
- data/lib/droonga/plugin_registry.rb +3 -1
- data/lib/droonga/plugins/basic.rb +1 -1
- data/lib/droonga/plugins/crud.rb +1 -1
- data/lib/droonga/plugins/dump.rb +13 -2
- data/lib/droonga/plugins/error.rb +1 -1
- data/lib/droonga/plugins/groonga/column_create.rb +1 -1
- data/lib/droonga/plugins/groonga/column_list.rb +1 -1
- data/lib/droonga/plugins/groonga/column_remove.rb +1 -1
- data/lib/droonga/plugins/groonga/column_rename.rb +1 -1
- data/lib/droonga/plugins/groonga/delete.rb +1 -1
- data/lib/droonga/plugins/groonga/generic_command.rb +1 -1
- data/lib/droonga/plugins/groonga/generic_response.rb +1 -1
- data/lib/droonga/plugins/groonga/select.rb +1 -1
- data/lib/droonga/plugins/groonga/table_create.rb +1 -1
- data/lib/droonga/plugins/groonga/table_list.rb +1 -1
- data/lib/droonga/plugins/groonga/table_remove.rb +1 -1
- data/lib/droonga/plugins/groonga.rb +1 -1
- data/lib/droonga/plugins/search/distributed_search_planner.rb +1 -1
- data/lib/droonga/plugins/search.rb +1 -1
- data/lib/droonga/plugins/system.rb +1 -1
- data/lib/droonga/plugins/watch.rb +1 -1
- data/lib/droonga/{service_control_protocol.rb → process_control_protocol.rb} +2 -2
- data/lib/droonga/process_supervisor.rb +91 -0
- data/lib/droonga/processor.rb +1 -1
- data/lib/droonga/reducer.rb +1 -1
- data/lib/droonga/replier.rb +2 -2
- data/lib/droonga/safe_file_writer.rb +1 -1
- data/lib/droonga/schema_applier.rb +1 -1
- data/lib/droonga/searcher/mecab_filter.rb +1 -1
- data/lib/droonga/searcher.rb +31 -19
- data/lib/droonga/serf.rb +81 -14
- data/lib/droonga/serf_downloader.rb +2 -2
- data/lib/droonga/session.rb +1 -1
- data/lib/droonga/single_step.rb +1 -1
- data/lib/droonga/single_step_definition.rb +1 -1
- data/lib/droonga/slice.rb +30 -28
- data/lib/droonga/status_code.rb +1 -1
- data/lib/droonga/step_runner.rb +1 -1
- data/lib/droonga/supervisor.rb +170 -0
- data/lib/droonga/sweeper.rb +1 -1
- data/lib/droonga/test/stub_handler.rb +1 -1
- data/lib/droonga/test/stub_handler_message.rb +1 -1
- data/lib/droonga/test/stub_handler_messenger.rb +1 -1
- data/lib/droonga/test/stub_planner.rb +1 -1
- data/lib/droonga/test.rb +1 -1
- data/lib/droonga/watch_schema.rb +2 -2
- data/lib/droonga/watcher.rb +1 -1
- data/lib/droonga/worker_process_agent.rb +111 -0
- data/sample/cluster/Rakefile +150 -0
- data/test/command/config/default/catalog.json +1 -34
- data/test/command/config/version1/catalog.json +3 -12
- data/test/command/run-test.rb +1 -1
- data/test/command/suite/dump/column/index.expected +19 -82
- data/test/command/suite/dump/column/scalar.expected +5 -36
- data/test/command/suite/dump/column/vector.expected +5 -39
- data/test/command/suite/dump/record/vector/reference.expected +24 -93
- data/test/command/suite/dump/table/array.expected +0 -19
- data/test/command/suite/dump/table/double_array_trie.expected +0 -20
- data/test/command/suite/dump/table/hash.expected +0 -20
- data/test/command/suite/dump/table/patricia_trie.expected +0 -20
- data/test/command/suite/search/condition/query/nonexistent_column.expected +0 -11
- data/test/command/suite/search/condition/query/syntax_error.expected +0 -11
- data/test/command/suite/search/error/unknown-source.expected +0 -12
- data/test/command/suite/search/output/attributes/invalid.expected +0 -10
- data/test/command/suite/search/output/attributes/reference_vector.catalog.json +27 -0
- data/test/command/suite/search/output/attributes/reference_vector.expected +30 -0
- data/test/command/suite/search/output/attributes/reference_vector.test +32 -0
- data/test/command/suite/watch/subscribe.catalog.json +23 -0
- data/test/command/suite/watch/subscribe.test +2 -0
- data/test/command/suite/watch/unsubscribe.catalog.json +23 -0
- data/test/command/suite/watch/unsubscribe.test +2 -0
- data/test/performance/run-test.rb +1 -1
- data/test/unit/catalog/test_collection_volume.rb +1 -1
- data/test/unit/catalog/test_dataset.rb +1 -1
- data/test/unit/catalog/test_schema.rb +1 -1
- data/test/unit/catalog/test_single_volume.rb +27 -19
- data/test/unit/catalog/test_slice.rb +2 -2
- data/test/unit/catalog/test_version1.rb +1 -1
- data/test/unit/catalog/test_version2.rb +1 -1
- data/test/unit/catalog/test_version2_validator.rb +1 -1
- data/test/unit/catalog/test_volume_collection.rb +1 -1
- data/test/unit/helper/distributed_search_planner_helper.rb +1 -1
- data/test/unit/helper/fixture.rb +1 -1
- data/test/unit/helper/plugin_helper.rb +1 -1
- data/test/unit/helper/sandbox.rb +1 -1
- data/test/unit/helper/stub_worker.rb +1 -1
- data/test/unit/helper/watch_helper.rb +1 -1
- data/test/unit/helper.rb +1 -1
- data/test/unit/plugins/crud/test_add.rb +1 -1
- data/test/unit/plugins/groonga/select/test_adapter_input.rb +1 -1
- data/test/unit/plugins/groonga/select/test_adapter_output.rb +1 -1
- data/test/unit/plugins/groonga/test_column_create.rb +1 -1
- data/test/unit/plugins/groonga/test_column_list.rb +1 -1
- data/test/unit/plugins/groonga/test_column_remove.rb +1 -1
- data/test/unit/plugins/groonga/test_column_rename.rb +1 -1
- data/test/unit/plugins/groonga/test_delete.rb +1 -1
- data/test/unit/plugins/groonga/test_table_create.rb +1 -1
- data/test/unit/plugins/groonga/test_table_list.rb +1 -1
- data/test/unit/plugins/groonga/test_table_remove.rb +1 -1
- data/test/unit/plugins/search/planner/test_basic.rb +1 -1
- data/test/unit/plugins/search/planner/test_group_by.rb +1 -1
- data/test/unit/plugins/search/planner/test_output.rb +1 -1
- data/test/unit/plugins/search/planner/test_sort_by.rb +1 -1
- data/test/unit/plugins/search/test_collector.rb +1 -1
- data/test/unit/plugins/search/test_handler.rb +1 -1
- data/test/unit/plugins/search/test_planner.rb +1 -1
- data/test/unit/plugins/system/test_status.rb +1 -1
- data/test/unit/plugins/test_basic.rb +1 -1
- data/test/unit/plugins/test_groonga.rb +1 -1
- data/test/unit/plugins/test_watch.rb +1 -1
- data/test/unit/run-test.rb +1 -1
- data/test/unit/test_address.rb +53 -0
- data/test/unit/test_catalog_generator.rb +59 -1
- data/test/unit/test_line_buffer.rb +1 -1
- data/test/unit/test_message_matcher.rb +1 -1
- data/test/unit/test_schema_applier.rb +1 -1
- data/test/unit/test_sweeper.rb +1 -1
- data/test/unit/test_watch_schema.rb +1 -1
- data/test/unit/test_watcher.rb +1 -1
- metadata +39 -24
- data/lib/droonga/server.rb +0 -45
- data/lib/droonga/worker.rb +0 -66
- data/sample/cluster/catalog.json +0 -42
- data/test/command/config/default/fluentd.conf +0 -11
- data/test/command/config/version1/fluentd.conf +0 -11
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
# You should have received a copy of the GNU Lesser General Public
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
|
-
# Foundation, Inc.,
|
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
15
15
|
|
|
16
16
|
require "json"
|
|
17
17
|
|
|
@@ -34,14 +34,22 @@ module Droonga
|
|
|
34
34
|
@serf = ENV["SERF"] || Serf.path
|
|
35
35
|
@serf_rpc_address = ENV["SERF_RPC_ADDRESS"] || "127.0.0.1:7373"
|
|
36
36
|
@serf_name = ENV["SERF_SELF_NAME"]
|
|
37
|
+
@response = {
|
|
38
|
+
"log" => []
|
|
39
|
+
}
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
def run
|
|
40
43
|
parse_event
|
|
41
|
-
|
|
44
|
+
unless event_for_me?
|
|
45
|
+
log(" => ignoring event not for me")
|
|
46
|
+
output_response
|
|
47
|
+
return true
|
|
48
|
+
end
|
|
42
49
|
|
|
43
50
|
process_event
|
|
44
51
|
output_live_nodes
|
|
52
|
+
output_response
|
|
45
53
|
true
|
|
46
54
|
end
|
|
47
55
|
|
|
@@ -53,11 +61,13 @@ module Droonga
|
|
|
53
61
|
when "user"
|
|
54
62
|
@event_sub_name = ENV["SERF_USER_EVENT"]
|
|
55
63
|
@payload = JSON.parse($stdin.gets)
|
|
56
|
-
|
|
64
|
+
log("event sub name = #{@event_sub_name}")
|
|
57
65
|
when "query"
|
|
58
66
|
@event_sub_name = ENV["SERF_QUERY_NAME"]
|
|
59
67
|
@payload = JSON.parse($stdin.gets)
|
|
60
|
-
|
|
68
|
+
log("event sub name = #{@event_sub_name}")
|
|
69
|
+
when "member-join", "member-leave", "member-update", "member-reap"
|
|
70
|
+
output_live_nodes
|
|
61
71
|
end
|
|
62
72
|
end
|
|
63
73
|
|
|
@@ -72,6 +82,8 @@ module Droonga
|
|
|
72
82
|
case @event_sub_name
|
|
73
83
|
when "change_role"
|
|
74
84
|
save_status(:role, @payload["role"])
|
|
85
|
+
when "report_status"
|
|
86
|
+
report_status
|
|
75
87
|
when "join"
|
|
76
88
|
join
|
|
77
89
|
when "set_replicas"
|
|
@@ -82,9 +94,17 @@ module Droonga
|
|
|
82
94
|
remove_replicas
|
|
83
95
|
when "absorb_data"
|
|
84
96
|
absorb_data
|
|
97
|
+
when "publish_catalog"
|
|
98
|
+
publish_catalog
|
|
99
|
+
when "unpublish_catalog"
|
|
100
|
+
unpublish_catalog
|
|
85
101
|
end
|
|
86
102
|
end
|
|
87
103
|
|
|
104
|
+
def output_response
|
|
105
|
+
puts JSON.generate(@response)
|
|
106
|
+
end
|
|
107
|
+
|
|
88
108
|
def host
|
|
89
109
|
@serf_name.split(":").first
|
|
90
110
|
end
|
|
@@ -96,9 +116,13 @@ module Droonga
|
|
|
96
116
|
hosts
|
|
97
117
|
end
|
|
98
118
|
|
|
119
|
+
def report_status
|
|
120
|
+
@response["value"] = status(@payload["key"].to_sym)
|
|
121
|
+
end
|
|
122
|
+
|
|
99
123
|
def join
|
|
100
124
|
type = @payload["type"]
|
|
101
|
-
|
|
125
|
+
log("type = #{type}")
|
|
102
126
|
case type
|
|
103
127
|
when "replica"
|
|
104
128
|
join_as_replica
|
|
@@ -106,55 +130,106 @@ module Droonga
|
|
|
106
130
|
end
|
|
107
131
|
|
|
108
132
|
def join_as_replica
|
|
109
|
-
|
|
110
|
-
return unless
|
|
133
|
+
source_node = @payload["source"]
|
|
134
|
+
return unless source_node
|
|
111
135
|
|
|
112
|
-
|
|
136
|
+
log("source_node = #{source_node}")
|
|
113
137
|
|
|
114
|
-
|
|
115
|
-
|
|
138
|
+
source_host = source_node.split(":").first
|
|
139
|
+
|
|
140
|
+
# fetch_port = @payload["fetch_port"]
|
|
141
|
+
# catalog = fetch_catalog(source_node, fetch_port)
|
|
142
|
+
catalog = JSON.parse(Path.catalog.read) #XXX workaround until "fetch" become available
|
|
143
|
+
|
|
144
|
+
generator = create_current_catalog_generator(catalog)
|
|
145
|
+
dataset = generator.dataset_for_host(source_host) ||
|
|
116
146
|
generator.dataset_for_host(host)
|
|
117
147
|
return unless dataset
|
|
118
148
|
|
|
149
|
+
# restart self with the fetched catalog.
|
|
150
|
+
SafeFileWriter.write(Path.catalog, JSON.pretty_generate(catalog))
|
|
151
|
+
|
|
119
152
|
dataset_name = dataset.name
|
|
120
153
|
tag = dataset.replicas.tag
|
|
121
154
|
port = dataset.replicas.port
|
|
122
155
|
other_hosts = dataset.replicas.hosts
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
157
|
+
log("dataset = #{dataset_name}")
|
|
158
|
+
log("port = #{port}")
|
|
159
|
+
log("tag = #{tag}")
|
|
127
160
|
|
|
128
161
|
if @payload["copy"]
|
|
129
|
-
|
|
162
|
+
log("starting to copy data from #{source_host}")
|
|
130
163
|
|
|
131
164
|
modify_catalog do |modifier|
|
|
132
165
|
modifier.datasets[dataset_name].replicas.hosts = [host]
|
|
133
166
|
end
|
|
134
|
-
sleep(
|
|
167
|
+
sleep(5) #TODO: wait for restart. this should be done more safely, to avoid starting of absorbing with old catalog.json.
|
|
135
168
|
|
|
169
|
+
save_status(:absorbing, true)
|
|
136
170
|
DataAbsorber.absorb(:dataset => dataset_name,
|
|
137
|
-
:source_host =>
|
|
171
|
+
:source_host => source_host,
|
|
138
172
|
:destination_host => host,
|
|
139
173
|
:port => port,
|
|
140
174
|
:tag => tag)
|
|
175
|
+
delete_status(:absorbing)
|
|
141
176
|
sleep(1)
|
|
142
177
|
end
|
|
143
178
|
|
|
144
|
-
|
|
179
|
+
log("joining to the cluster: update myself")
|
|
145
180
|
|
|
146
181
|
modify_catalog do |modifier|
|
|
147
182
|
modifier.datasets[dataset_name].replicas.hosts += other_hosts
|
|
148
183
|
modifier.datasets[dataset_name].replicas.hosts.uniq!
|
|
149
184
|
end
|
|
150
|
-
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def fetch_catalog(source_node, port)
|
|
188
|
+
source_host = source_node.split(":").first
|
|
189
|
+
|
|
190
|
+
url = "http://#{source_host}:#{port}"
|
|
191
|
+
connection = Faraday.new(url) do |builder|
|
|
192
|
+
builder.response(:follow_redirects)
|
|
193
|
+
builder.adapter(Faraday.default_adapter)
|
|
194
|
+
end
|
|
195
|
+
response = connection.get("/catalog.json")
|
|
196
|
+
catalog = response.body
|
|
197
|
+
|
|
198
|
+
JSON.parse(catalog)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def publish_catalog
|
|
202
|
+
port = @payload["port"]
|
|
203
|
+
return unless port
|
|
204
|
+
|
|
205
|
+
env = {}
|
|
206
|
+
publisher_command_line = [
|
|
207
|
+
"droonga-engine-data-publisher",
|
|
208
|
+
"--base-dir", Path.base.to_s,
|
|
209
|
+
"--port", port.to_s,
|
|
210
|
+
"--published-file", Path.catalog.to_s
|
|
211
|
+
]
|
|
212
|
+
pid = spawn(env, *publisher_command_line)
|
|
213
|
+
Process.detach(pid)
|
|
214
|
+
sleep(1) # wait until the directory is published
|
|
215
|
+
|
|
216
|
+
published_dir = Path.published(port)
|
|
217
|
+
pid_file = published_dir + ".pid"
|
|
218
|
+
|
|
219
|
+
File.open(pid_file.to_s, "w") do |file|
|
|
220
|
+
file.puts(pid)
|
|
221
|
+
end
|
|
222
|
+
end
|
|
151
223
|
|
|
152
|
-
|
|
224
|
+
def unpublish_catalog
|
|
225
|
+
port = @payload["port"]
|
|
226
|
+
return unless port
|
|
153
227
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
228
|
+
published_dir = Path.published(port)
|
|
229
|
+
pid_file = published_dir + ".pid"
|
|
230
|
+
pid = pid_file.read.to_i
|
|
231
|
+
|
|
232
|
+
Process.kill("INT", pid)
|
|
158
233
|
end
|
|
159
234
|
|
|
160
235
|
def set_replicas
|
|
@@ -164,7 +239,7 @@ module Droonga
|
|
|
164
239
|
hosts = given_hosts
|
|
165
240
|
return unless hosts
|
|
166
241
|
|
|
167
|
-
|
|
242
|
+
log("new replicas: #{hosts.join(",")}")
|
|
168
243
|
|
|
169
244
|
modify_catalog do |modifier|
|
|
170
245
|
modifier.datasets[dataset].replicas.hosts = hosts
|
|
@@ -181,7 +256,7 @@ module Droonga
|
|
|
181
256
|
hosts -= [host]
|
|
182
257
|
return if hosts.empty?
|
|
183
258
|
|
|
184
|
-
|
|
259
|
+
log("adding replicas: #{hosts.join(",")}")
|
|
185
260
|
|
|
186
261
|
modify_catalog do |modifier|
|
|
187
262
|
modifier.datasets[dataset].replicas.hosts += hosts
|
|
@@ -196,7 +271,7 @@ module Droonga
|
|
|
196
271
|
hosts = given_hosts
|
|
197
272
|
return unless hosts
|
|
198
273
|
|
|
199
|
-
|
|
274
|
+
log("removing replicas: #{hosts.join(",")}")
|
|
200
275
|
|
|
201
276
|
modify_catalog do |modifier|
|
|
202
277
|
modifier.datasets[dataset].replicas.hosts -= hosts
|
|
@@ -209,19 +284,17 @@ module Droonga
|
|
|
209
284
|
SafeFileWriter.write(Path.catalog, JSON.pretty_generate(generator.generate))
|
|
210
285
|
end
|
|
211
286
|
|
|
212
|
-
def create_current_catalog_generator
|
|
213
|
-
current_catalog
|
|
287
|
+
def create_current_catalog_generator(current_catalog=nil)
|
|
288
|
+
current_catalog ||= JSON.parse(Path.catalog.read)
|
|
214
289
|
generator = CatalogGenerator.new
|
|
215
290
|
generator.load(current_catalog)
|
|
216
291
|
end
|
|
217
292
|
|
|
218
293
|
def absorb_data
|
|
219
|
-
return unless event_for_me?
|
|
220
|
-
|
|
221
294
|
source = @payload["source"]
|
|
222
295
|
return unless source
|
|
223
296
|
|
|
224
|
-
|
|
297
|
+
log("start to absorb data from #{source}")
|
|
225
298
|
|
|
226
299
|
dataset_name = @payload["dataset"]
|
|
227
300
|
port = @payload["port"]
|
|
@@ -240,29 +313,22 @@ module Droonga
|
|
|
240
313
|
tag = dataset.replicas.tag
|
|
241
314
|
end
|
|
242
315
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
316
|
+
log("dataset = #{dataset_name}")
|
|
317
|
+
log("port = #{port}")
|
|
318
|
+
log("tag = #{tag}")
|
|
246
319
|
|
|
320
|
+
save_status(:absorbing, true)
|
|
247
321
|
DataAbsorber.absorb(:dataset => dataset_name,
|
|
248
322
|
:source_host => source,
|
|
249
323
|
:destination_host => host,
|
|
250
324
|
:port => port,
|
|
251
|
-
:tag => tag
|
|
325
|
+
:tag => tag,
|
|
326
|
+
:client => "droonga-send")
|
|
327
|
+
delete_status(:absorbing)
|
|
252
328
|
end
|
|
253
329
|
|
|
254
330
|
def live_nodes
|
|
255
|
-
|
|
256
|
-
members = `#{@serf} members -rpc-addr #{@serf_rpc_address}`
|
|
257
|
-
members.each_line do |member|
|
|
258
|
-
name, address, status, = member.strip.split(/\s+/)
|
|
259
|
-
if status == "alive"
|
|
260
|
-
nodes[name] = {
|
|
261
|
-
"serfAddress" => address,
|
|
262
|
-
}
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
nodes
|
|
331
|
+
Serf.live_nodes(@serf_name)
|
|
266
332
|
end
|
|
267
333
|
|
|
268
334
|
def output_live_nodes
|
|
@@ -272,11 +338,25 @@ module Droonga
|
|
|
272
338
|
SafeFileWriter.write(path, file_contents)
|
|
273
339
|
end
|
|
274
340
|
|
|
341
|
+
def status(key)
|
|
342
|
+
Serf.status(key)
|
|
343
|
+
end
|
|
344
|
+
|
|
275
345
|
def save_status(key, value)
|
|
276
346
|
status = Serf.load_status
|
|
277
347
|
status[key] = value
|
|
278
348
|
SafeFileWriter.write(Serf.status_file, JSON.pretty_generate(status))
|
|
279
349
|
end
|
|
350
|
+
|
|
351
|
+
def delete_status(key)
|
|
352
|
+
status = Serf.load_status
|
|
353
|
+
status.delete(key)
|
|
354
|
+
SafeFileWriter.write(Serf.status_file, JSON.pretty_generate(status))
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def log(message)
|
|
358
|
+
@response["log"] << message
|
|
359
|
+
end
|
|
280
360
|
end
|
|
281
361
|
end
|
|
282
362
|
end
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
# You should have received a copy of the GNU Lesser General Public
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
|
-
# Foundation, Inc.,
|
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
15
15
|
|
|
16
16
|
require "open3"
|
|
17
17
|
|
|
@@ -28,25 +28,43 @@ module Droonga
|
|
|
28
28
|
drndump_options += ["--receiver-host", params[:destination_host]]
|
|
29
29
|
drndump_options += ["--receiver-port", params[:receiver_port].to_s] if params[:receiver_port]
|
|
30
30
|
|
|
31
|
+
#TODO: We should use droonga-send instead of droonga-request,
|
|
32
|
+
# because droonga-request is too slow.
|
|
33
|
+
# However, to do it, we have to implement an API to know
|
|
34
|
+
# that all messages sent by droonga-send are completely
|
|
35
|
+
# processed.
|
|
31
36
|
client = params[:client] || "droonga-request"
|
|
32
37
|
client_options = []
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
if client.include?("droonga-request")
|
|
39
|
+
client_options += ["--host", params[:destination_host]]
|
|
40
|
+
client_options += ["--port", params[:port].to_s] if params[:port]
|
|
41
|
+
client_options += ["--tag", params[:tag]] if params[:tag]
|
|
42
|
+
client_options += ["--receiver-host", params[:destination_host]]
|
|
43
|
+
client_options += ["--receiver-port", params[:receiver_port].to_s] if params[:receiver_port]
|
|
44
|
+
elsif client.include?("droonga-send")
|
|
45
|
+
#XXX Don't use round-robin with multiple endpoints
|
|
46
|
+
# even if there are too much data.
|
|
47
|
+
# Schema and indexes must be sent to just one endpoint
|
|
48
|
+
# to keep their order, but currently there is no way to
|
|
49
|
+
# extract only schema and indexes via drndump.
|
|
50
|
+
# So, we always use just one endpoint for now,
|
|
51
|
+
# even if there are too much data.
|
|
52
|
+
server = "droonga:#{params[:destination_host]}"
|
|
53
|
+
server = "#{server}:#{params[:port].to_s}" if params[:port]
|
|
54
|
+
server = "#{server}/#{params[:tag].to_s}" if params[:tag]
|
|
55
|
+
client_options += ["--server", server]
|
|
56
|
+
else
|
|
57
|
+
raise ArgumentError.new("Unknwon type client: #{client}")
|
|
58
|
+
end
|
|
38
59
|
|
|
39
60
|
drndump_command_line = [drndump] + drndump_options
|
|
40
61
|
client_command_line = [client] + client_options
|
|
41
62
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
yield dump if block_given?
|
|
48
|
-
client_in.puts(dump)
|
|
49
|
-
end
|
|
63
|
+
env = {}
|
|
64
|
+
Open3.pipeline_r([env, *drndump_command_line],
|
|
65
|
+
[env, *client_command_line]) do |last_stdout, thread|
|
|
66
|
+
last_stdout.each do |output|
|
|
67
|
+
yield output if block_given?
|
|
50
68
|
end
|
|
51
69
|
end
|
|
52
70
|
end
|
data/lib/droonga/dispatcher.rb
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
# You should have received a copy of the GNU Lesser General Public
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
|
-
# Foundation, Inc.,
|
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
15
15
|
|
|
16
16
|
require "tsort"
|
|
17
17
|
|
|
@@ -63,6 +63,9 @@ module Droonga
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def start
|
|
66
|
+
@farm.on_ready = lambda do
|
|
67
|
+
@engine_state.on_ready
|
|
68
|
+
end
|
|
66
69
|
@farm.start
|
|
67
70
|
end
|
|
68
71
|
|
|
@@ -143,10 +146,10 @@ module Droonga
|
|
|
143
146
|
else
|
|
144
147
|
steps = message["steps"]
|
|
145
148
|
if steps
|
|
146
|
-
session_planner = SessionPlanner.new(
|
|
149
|
+
session_planner = SessionPlanner.new(@engine_state, steps)
|
|
147
150
|
dataset = message["dataset"] || @message["dataset"]
|
|
148
151
|
collector_runner = @collector_runners[dataset]
|
|
149
|
-
session = session_planner.create_session(id, collector_runner)
|
|
152
|
+
session = session_planner.create_session(id, self, collector_runner)
|
|
150
153
|
@engine_state.register_session(id, session)
|
|
151
154
|
else
|
|
152
155
|
logger.error("no steps error: id=#{id}, message=#{message}")
|
|
@@ -175,7 +178,7 @@ module Droonga
|
|
|
175
178
|
steps.each do |step|
|
|
176
179
|
dataset = @catalog.dataset(step["dataset"])
|
|
177
180
|
if dataset
|
|
178
|
-
routes = dataset.
|
|
181
|
+
routes = dataset.compute_routes(step, @engine_state.live_nodes)
|
|
179
182
|
step["routes"] = routes
|
|
180
183
|
else
|
|
181
184
|
step["routes"] ||= [id]
|
|
@@ -279,24 +282,24 @@ module Droonga
|
|
|
279
282
|
end
|
|
280
283
|
|
|
281
284
|
def log_tag
|
|
282
|
-
"
|
|
285
|
+
"dispatcher"
|
|
283
286
|
end
|
|
284
287
|
|
|
285
288
|
class SessionPlanner
|
|
286
289
|
attr_reader :steps
|
|
287
290
|
|
|
288
|
-
def initialize(
|
|
289
|
-
@
|
|
291
|
+
def initialize(engine_state, steps)
|
|
292
|
+
@engine_state = engine_state
|
|
290
293
|
@steps = steps
|
|
291
294
|
end
|
|
292
295
|
|
|
293
|
-
def create_session(id, collector_runner)
|
|
296
|
+
def create_session(id, dispatcher, collector_runner)
|
|
294
297
|
resolve_descendants
|
|
295
298
|
tasks = []
|
|
296
299
|
inputs = {}
|
|
297
300
|
@steps.each do |step|
|
|
298
301
|
step["routes"].each do |route|
|
|
299
|
-
next unless @
|
|
302
|
+
next unless @engine_state.local_route?(route)
|
|
300
303
|
task = {
|
|
301
304
|
"route" => route,
|
|
302
305
|
"step" => step,
|
|
@@ -310,7 +313,7 @@ module Droonga
|
|
|
310
313
|
end
|
|
311
314
|
end
|
|
312
315
|
end
|
|
313
|
-
Session.new(id,
|
|
316
|
+
Session.new(id, dispatcher, collector_runner, tasks, inputs)
|
|
314
317
|
end
|
|
315
318
|
|
|
316
319
|
def resolve_descendants
|
|
@@ -328,7 +331,8 @@ module Droonga
|
|
|
328
331
|
(step["outputs"] || []).each do |output|
|
|
329
332
|
descendants[output] = []
|
|
330
333
|
@descendants[output].each do |index|
|
|
331
|
-
|
|
334
|
+
live_routes = @engine_state.remove_dead_routes(step["routes"])
|
|
335
|
+
@steps[index]["n_of_expects"] += live_routes.size
|
|
332
336
|
descendants[output].concat(@steps[index]["routes"])
|
|
333
337
|
end
|
|
334
338
|
end
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#
|
|
14
14
|
# You should have received a copy of the GNU Lesser General Public
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
|
-
# Foundation, Inc.,
|
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
|
|
18
18
|
module Droonga
|
|
19
19
|
class DistributedCommandPlanner
|
data/lib/droonga/distributor.rb
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#
|
|
14
14
|
# You should have received a copy of the GNU Lesser General Public
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
|
-
# Foundation, Inc.,
|
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
|
|
18
18
|
require "tsort"
|
|
19
19
|
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
#
|
|
12
12
|
# You should have received a copy of the GNU Lesser General Public
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
|
-
# Foundation, Inc.,
|
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
15
15
|
|
|
16
16
|
module Droonga
|
|
17
17
|
class Engine
|
|
18
|
-
VERSION = "1.0.
|
|
18
|
+
VERSION = "1.0.5"
|
|
19
19
|
end
|
|
20
20
|
end
|
data/lib/droonga/engine.rb
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#
|
|
14
14
|
# You should have received a copy of the GNU Lesser General Public
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
|
-
# Foundation, Inc.,
|
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
|
|
18
18
|
require "time"
|
|
19
19
|
require "fileutils"
|
|
@@ -29,6 +29,7 @@ module Droonga
|
|
|
29
29
|
class Engine
|
|
30
30
|
include Loggable
|
|
31
31
|
|
|
32
|
+
attr_writer :on_ready
|
|
32
33
|
def initialize(loop, name, internal_name)
|
|
33
34
|
@state = EngineState.new(loop, name, internal_name)
|
|
34
35
|
@catalog = load_catalog
|
|
@@ -38,10 +39,14 @@ module Droonga
|
|
|
38
39
|
@live_nodes_list_observer.on_change = lambda do
|
|
39
40
|
@state.live_nodes = load_live_nodes
|
|
40
41
|
end
|
|
42
|
+
@on_ready = nil
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
def start
|
|
44
46
|
logger.trace("start: start")
|
|
47
|
+
@state.on_ready = lambda do
|
|
48
|
+
@on_ready.call if @on_ready
|
|
49
|
+
end
|
|
45
50
|
@state.start
|
|
46
51
|
@live_nodes_list_observer.start
|
|
47
52
|
@dispatcher.start
|
|
@@ -87,7 +92,7 @@ module Droonga
|
|
|
87
92
|
loader = CatalogLoader.new(catalog_path.to_s)
|
|
88
93
|
catalog = loader.load
|
|
89
94
|
logger.info("catalog loaded",
|
|
90
|
-
:path => catalog_path,
|
|
95
|
+
:path => catalog_path.to_s,
|
|
91
96
|
:mtime => catalog_path.mtime)
|
|
92
97
|
catalog
|
|
93
98
|
end
|
|
@@ -97,7 +102,7 @@ module Droonga
|
|
|
97
102
|
loader = LiveNodesListLoader.new(path)
|
|
98
103
|
live_nodes = loader.load
|
|
99
104
|
logger.info("live-nodes loaded",
|
|
100
|
-
:path => path,
|
|
105
|
+
:path => path.to_s,
|
|
101
106
|
:mtime => path.mtime)
|
|
102
107
|
live_nodes
|
|
103
108
|
end
|
data/lib/droonga/engine_state.rb
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
# You should have received a copy of the GNU Lesser General Public
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
|
-
# Foundation, Inc.,
|
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
15
15
|
|
|
16
16
|
require "English"
|
|
17
17
|
|
|
@@ -31,21 +31,22 @@ module Droonga
|
|
|
31
31
|
attr_reader :internal_name
|
|
32
32
|
attr_reader :forwarder
|
|
33
33
|
attr_reader :replier
|
|
34
|
+
attr_writer :on_ready
|
|
34
35
|
attr_accessor :on_finish
|
|
35
36
|
attr_accessor :catalog
|
|
36
|
-
attr_writer :dead_nodes
|
|
37
37
|
def initialize(loop, name, internal_name)
|
|
38
38
|
@loop = loop
|
|
39
39
|
@name = name
|
|
40
40
|
@internal_name = internal_name
|
|
41
41
|
@sessions = {}
|
|
42
42
|
@current_id = 0
|
|
43
|
-
@forwarder = Forwarder.new(@loop)
|
|
44
|
-
@forwarder.resume
|
|
43
|
+
@forwarder = Forwarder.new(@loop, :buffering => true)
|
|
45
44
|
@replier = Replier.new(@forwarder)
|
|
45
|
+
@on_ready = nil
|
|
46
46
|
@on_finish = nil
|
|
47
47
|
@catalog = nil
|
|
48
48
|
@live_nodes = nil
|
|
49
|
+
@dead_nodes = []
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
def start
|
|
@@ -111,13 +112,21 @@ module Droonga
|
|
|
111
112
|
end
|
|
112
113
|
|
|
113
114
|
def live_nodes=(nodes)
|
|
115
|
+
old_live_nodes = @live_nodes
|
|
114
116
|
@live_nodes = nodes
|
|
115
117
|
@dead_nodes = all_nodes - @live_nodes
|
|
118
|
+
@forwarder.resume if old_live_nodes != @live_nodes
|
|
116
119
|
@live_nodes
|
|
117
120
|
end
|
|
118
121
|
|
|
119
|
-
def
|
|
120
|
-
|
|
122
|
+
def remove_dead_routes(routes)
|
|
123
|
+
routes.reject do |route|
|
|
124
|
+
@dead_nodes.include?(farm_path(route))
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def on_ready
|
|
129
|
+
@on_ready.call if @on_ready
|
|
121
130
|
end
|
|
122
131
|
|
|
123
132
|
private
|
data/lib/droonga/error.rb
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#
|
|
14
14
|
# You should have received a copy of the GNU Lesser General Public
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
|
-
# Foundation, Inc.,
|
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
|
|
18
18
|
module Droonga
|
|
19
19
|
class Error < StandardError
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
# You should have received a copy of the GNU Lesser General Public
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
|
14
|
-
# Foundation, Inc.,
|
|
14
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
15
15
|
|
|
16
16
|
require "droonga/error"
|
|
17
17
|
require "droonga/status_code"
|
data/lib/droonga/event_loop.rb
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
#
|
|
14
14
|
# You should have received a copy of the GNU Lesser General Public
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
|
-
# Foundation, Inc.,
|
|
16
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
17
|
|
|
18
18
|
require "coolio"
|
|
19
19
|
|