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 "optparse"
|
|
17
17
|
require "socket"
|
|
@@ -24,8 +24,7 @@ require "sigdump"
|
|
|
24
24
|
require "droonga/path"
|
|
25
25
|
require "droonga/serf"
|
|
26
26
|
require "droonga/file_observer"
|
|
27
|
-
require "droonga/
|
|
28
|
-
require "droonga/line_buffer"
|
|
27
|
+
require "droonga/process_supervisor"
|
|
29
28
|
|
|
30
29
|
module Droonga
|
|
31
30
|
module Command
|
|
@@ -94,14 +93,14 @@ module Droonga
|
|
|
94
93
|
end
|
|
95
94
|
|
|
96
95
|
def write_pid_file
|
|
97
|
-
if @configuration.
|
|
98
|
-
|
|
96
|
+
if @configuration.pid_file_path
|
|
97
|
+
@configuration.pid_file_path.open("w") do |file|
|
|
99
98
|
file.puts(Process.pid)
|
|
100
99
|
end
|
|
101
100
|
begin
|
|
102
101
|
yield
|
|
103
102
|
ensure
|
|
104
|
-
FileUtils.rm_f(@configuration.
|
|
103
|
+
FileUtils.rm_f(@configuration.pid_file_path.to_s)
|
|
105
104
|
end
|
|
106
105
|
else
|
|
107
106
|
yield
|
|
@@ -112,14 +111,16 @@ module Droonga
|
|
|
112
111
|
DEFAULT_HOST = Socket.gethostname
|
|
113
112
|
DEFAULT_PORT = 10031
|
|
114
113
|
|
|
115
|
-
attr_reader :host, :port, :tag, :log_file, :
|
|
114
|
+
attr_reader :host, :port, :tag, :log_file, :pid_file_path
|
|
115
|
+
attr_reader :ready_notify_fd
|
|
116
116
|
def initialize
|
|
117
117
|
@host = DEFAULT_HOST
|
|
118
118
|
@port = DEFAULT_PORT
|
|
119
119
|
@tag = "droonga"
|
|
120
120
|
@log_file = nil
|
|
121
121
|
@daemon = false
|
|
122
|
-
@
|
|
122
|
+
@pid_file_path = nil
|
|
123
|
+
@ready_notify_fd = nil
|
|
123
124
|
end
|
|
124
125
|
|
|
125
126
|
def engine_name
|
|
@@ -151,6 +152,7 @@ module Droonga
|
|
|
151
152
|
add_log_options(parser)
|
|
152
153
|
add_process_options(parser)
|
|
153
154
|
add_path_options(parser)
|
|
155
|
+
add_notification_options(parser)
|
|
154
156
|
end
|
|
155
157
|
|
|
156
158
|
def listen_socket
|
|
@@ -206,9 +208,9 @@ module Droonga
|
|
|
206
208
|
"Run as a daemon") do
|
|
207
209
|
@daemon = true
|
|
208
210
|
end
|
|
209
|
-
parser.on("--pid-file=
|
|
210
|
-
"Put PID to
|
|
211
|
-
@
|
|
211
|
+
parser.on("--pid-file=PATH",
|
|
212
|
+
"Put PID to PATH") do |path|
|
|
213
|
+
@pid_file_path = Pathname.new(path).expand_path
|
|
212
214
|
end
|
|
213
215
|
end
|
|
214
216
|
|
|
@@ -222,6 +224,15 @@ module Droonga
|
|
|
222
224
|
end
|
|
223
225
|
end
|
|
224
226
|
|
|
227
|
+
def add_notification_options(parser)
|
|
228
|
+
parser.separator("")
|
|
229
|
+
parser.separator("Notification:")
|
|
230
|
+
parser.on("--ready-notify-fd=FD", Integer,
|
|
231
|
+
"Send 'ready' message to FD on ready") do |fd|
|
|
232
|
+
@ready_notify_fd = fd
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
225
236
|
def bind_heartbeat_socket
|
|
226
237
|
socket = UDPSocket.new(address_family)
|
|
227
238
|
socket.bind(@host, @port)
|
|
@@ -239,36 +250,45 @@ module Droonga
|
|
|
239
250
|
@serf = run_serf
|
|
240
251
|
@serf_status_observer = run_serf_status_observer
|
|
241
252
|
@service_runner = run_service
|
|
253
|
+
setup_initial_on_ready
|
|
242
254
|
@catalog_observer = run_catalog_observer
|
|
243
|
-
@
|
|
244
|
-
@loop.attach(@loop_breaker)
|
|
255
|
+
@command_runner = run_command_runner
|
|
245
256
|
|
|
246
257
|
trap_signals
|
|
247
258
|
@loop.run
|
|
248
|
-
@serf.
|
|
259
|
+
@serf.stop if @serf.running?
|
|
249
260
|
|
|
250
261
|
@service_runner.success?
|
|
251
262
|
end
|
|
252
263
|
|
|
253
264
|
private
|
|
265
|
+
def setup_initial_on_ready
|
|
266
|
+
return if @configuration.ready_notify_fd.nil?
|
|
267
|
+
@service_runner.on_ready = lambda do
|
|
268
|
+
output = IO.new(@configuration.ready_notify_fd)
|
|
269
|
+
output.puts("ready")
|
|
270
|
+
output.close
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
254
274
|
def trap_signals
|
|
255
275
|
trap(:TERM) do
|
|
256
|
-
stop_gracefully
|
|
276
|
+
@command_runner.push_command(:stop_gracefully)
|
|
257
277
|
trap(:TERM, "DEFAULT")
|
|
258
278
|
end
|
|
259
279
|
trap(:INT) do
|
|
260
|
-
stop_immediately
|
|
280
|
+
@command_runner.push_command(:stop_immediately)
|
|
261
281
|
trap(:INT, "DEFAULT")
|
|
262
282
|
end
|
|
263
283
|
trap(:QUIT) do
|
|
264
|
-
stop_immediately
|
|
284
|
+
@command_runner.push_cmmand(:stop_immediately)
|
|
265
285
|
trap(:QUIT, "DEFAULT")
|
|
266
286
|
end
|
|
267
287
|
trap(:USR1) do
|
|
268
|
-
restart_graceful
|
|
288
|
+
@command_runner.push_command(:restart_graceful)
|
|
269
289
|
end
|
|
270
290
|
trap(:HUP) do
|
|
271
|
-
restart_immediately
|
|
291
|
+
@command_runner.push_command(:restart_immediately)
|
|
272
292
|
end
|
|
273
293
|
trap(:USR2) do
|
|
274
294
|
Sigdump.dump
|
|
@@ -276,25 +296,22 @@ module Droonga
|
|
|
276
296
|
end
|
|
277
297
|
|
|
278
298
|
def stop_gracefully
|
|
279
|
-
@
|
|
280
|
-
@
|
|
281
|
-
@serf.shutdown
|
|
299
|
+
@command_runner.stop
|
|
300
|
+
@serf.stop
|
|
282
301
|
@serf_status_observer.stop
|
|
283
302
|
@catalog_observer.stop
|
|
284
303
|
@service_runner.stop_gracefully
|
|
285
304
|
end
|
|
286
305
|
|
|
287
306
|
def stop_immediately
|
|
288
|
-
@
|
|
289
|
-
@
|
|
290
|
-
@serf.shutdown
|
|
307
|
+
@command_runner.stop
|
|
308
|
+
@serf.stop
|
|
291
309
|
@serf_status_observer.stop
|
|
292
310
|
@catalog_observer.stop
|
|
293
311
|
@service_runner.stop_immediately
|
|
294
312
|
end
|
|
295
313
|
|
|
296
314
|
def restart_graceful
|
|
297
|
-
@loop_breaker.signal
|
|
298
315
|
old_service_runner = @service_runner
|
|
299
316
|
@service_runner = run_service
|
|
300
317
|
@service_runner.on_ready = lambda do
|
|
@@ -308,7 +325,6 @@ module Droonga
|
|
|
308
325
|
end
|
|
309
326
|
|
|
310
327
|
def restart_immediately
|
|
311
|
-
@loop_breaker.signal
|
|
312
328
|
old_service_runner = @service_runner
|
|
313
329
|
@service_runner = run_service
|
|
314
330
|
old_service_runner.stop_immediately
|
|
@@ -327,7 +343,7 @@ module Droonga
|
|
|
327
343
|
end
|
|
328
344
|
|
|
329
345
|
def restart_serf
|
|
330
|
-
@serf.
|
|
346
|
+
@serf.stop if @serf
|
|
331
347
|
@serf = run_serf
|
|
332
348
|
end
|
|
333
349
|
|
|
@@ -348,11 +364,18 @@ module Droonga
|
|
|
348
364
|
catalog_observer.start
|
|
349
365
|
catalog_observer
|
|
350
366
|
end
|
|
367
|
+
|
|
368
|
+
def run_command_runner
|
|
369
|
+
command_runner = CommandRunner.new(@loop)
|
|
370
|
+
command_runner.on_command = lambda do |command|
|
|
371
|
+
__send__(command)
|
|
372
|
+
end
|
|
373
|
+
command_runner.start
|
|
374
|
+
command_runner
|
|
375
|
+
end
|
|
351
376
|
end
|
|
352
377
|
|
|
353
378
|
class ServiceRunner
|
|
354
|
-
include ServiceControlProtocol
|
|
355
|
-
|
|
356
379
|
def initialize(raw_loop, configuration)
|
|
357
380
|
@raw_loop = raw_loop
|
|
358
381
|
@configuration = configuration
|
|
@@ -394,16 +417,17 @@ module Droonga
|
|
|
394
417
|
@pid = spawn(env, *command_line, options)
|
|
395
418
|
control_write_in.close
|
|
396
419
|
control_read_out.close
|
|
397
|
-
|
|
398
|
-
|
|
420
|
+
@supervisor = create_process_supervisor(control_read_in,
|
|
421
|
+
control_write_out)
|
|
422
|
+
@supervisor.start
|
|
399
423
|
end
|
|
400
424
|
|
|
401
425
|
def stop_gracefully
|
|
402
|
-
@
|
|
426
|
+
@supervisor.stop_gracefully
|
|
403
427
|
end
|
|
404
428
|
|
|
405
429
|
def stop_immediately
|
|
406
|
-
@
|
|
430
|
+
@supervisor.stop_immediately
|
|
407
431
|
end
|
|
408
432
|
|
|
409
433
|
def success?
|
|
@@ -411,6 +435,17 @@ module Droonga
|
|
|
411
435
|
end
|
|
412
436
|
|
|
413
437
|
private
|
|
438
|
+
def create_process_supervisor(input, output)
|
|
439
|
+
supervisor = ProcessSupervisor.new(@raw_loop, input, output)
|
|
440
|
+
supervisor.on_ready = lambda do
|
|
441
|
+
on_ready
|
|
442
|
+
end
|
|
443
|
+
supervisor.on_finish = lambda do
|
|
444
|
+
on_finish
|
|
445
|
+
end
|
|
446
|
+
supervisor
|
|
447
|
+
end
|
|
448
|
+
|
|
414
449
|
def on_ready
|
|
415
450
|
@on_ready.call if @on_ready
|
|
416
451
|
end
|
|
@@ -422,33 +457,46 @@ module Droonga
|
|
|
422
457
|
def on_finish
|
|
423
458
|
_, status = Process.waitpid2(@pid)
|
|
424
459
|
@success = status.success?
|
|
425
|
-
@
|
|
426
|
-
@control_read_in.close
|
|
460
|
+
@supervisor.stop
|
|
427
461
|
on_failure unless success?
|
|
428
462
|
end
|
|
463
|
+
end
|
|
429
464
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
465
|
+
class CommandRunner
|
|
466
|
+
attr_writer :on_command
|
|
467
|
+
def initialize(loop)
|
|
468
|
+
@loop = loop
|
|
469
|
+
@commands = []
|
|
470
|
+
@on_command = nil
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def start
|
|
474
|
+
@async_watcher = Coolio::AsyncWatcher.new
|
|
475
|
+
on_signal = lambda do
|
|
476
|
+
commands = @commands.uniq
|
|
477
|
+
@commands.clear
|
|
478
|
+
until commands.empty?
|
|
479
|
+
command = commands.shift
|
|
480
|
+
@on_command.call(command) if @on_command
|
|
446
481
|
end
|
|
447
482
|
end
|
|
448
|
-
@
|
|
449
|
-
|
|
483
|
+
@async_watcher.on_signal do
|
|
484
|
+
on_signal.call
|
|
450
485
|
end
|
|
451
|
-
@
|
|
486
|
+
@loop.attach(@async_watcher)
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def stop
|
|
490
|
+
return if @async_watcher.nil?
|
|
491
|
+
@async_watcher.detach
|
|
492
|
+
@async_watcher = nil
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
def push_command(command)
|
|
496
|
+
return if @async_watcher.nil?
|
|
497
|
+
first_command_p = @commands.empty?
|
|
498
|
+
@commands << command
|
|
499
|
+
@async_watcher.signal if first_command_p
|
|
452
500
|
end
|
|
453
501
|
end
|
|
454
502
|
end
|
|
@@ -11,14 +11,13 @@
|
|
|
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 "optparse"
|
|
17
17
|
|
|
18
18
|
require "coolio"
|
|
19
19
|
|
|
20
|
-
require "droonga/
|
|
21
|
-
require "droonga/line_buffer"
|
|
20
|
+
require "droonga/worker_process_agent"
|
|
22
21
|
require "droonga/engine"
|
|
23
22
|
require "droonga/fluent_message_receiver"
|
|
24
23
|
require "droonga/internal_fluent_message_receiver"
|
|
@@ -34,7 +33,6 @@ module Droonga
|
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
include Loggable
|
|
37
|
-
include ServiceControlProtocol
|
|
38
36
|
|
|
39
37
|
def initialize
|
|
40
38
|
@engine_name = nil
|
|
@@ -59,10 +57,7 @@ module Droonga
|
|
|
59
57
|
logger.exception("failed to run services", $!)
|
|
60
58
|
success = false
|
|
61
59
|
ensure
|
|
62
|
-
|
|
63
|
-
control_write_io.write(Messages::FINISH)
|
|
64
|
-
control_write_io.close
|
|
65
|
-
end
|
|
60
|
+
shutdown_worker_process_agent
|
|
66
61
|
end
|
|
67
62
|
|
|
68
63
|
success
|
|
@@ -118,9 +113,9 @@ module Droonga
|
|
|
118
113
|
@loop = Coolio::Loop.default
|
|
119
114
|
|
|
120
115
|
run_internal_message_receiver
|
|
116
|
+
run_worker_process_agent
|
|
121
117
|
run_engine
|
|
122
118
|
run_receiver
|
|
123
|
-
run_control_io
|
|
124
119
|
@loop.run
|
|
125
120
|
end
|
|
126
121
|
|
|
@@ -145,6 +140,9 @@ module Droonga
|
|
|
145
140
|
|
|
146
141
|
def run_engine
|
|
147
142
|
@engine = Engine.new(@loop, @engine_name, @internal_engine_name)
|
|
143
|
+
@engine.on_ready = lambda do
|
|
144
|
+
@worker_process_agent.ready
|
|
145
|
+
end
|
|
148
146
|
@engine.start
|
|
149
147
|
end
|
|
150
148
|
|
|
@@ -153,66 +151,23 @@ module Droonga
|
|
|
153
151
|
@receiver.start
|
|
154
152
|
end
|
|
155
153
|
|
|
156
|
-
def
|
|
157
|
-
|
|
158
|
-
@receiver, receiver = nil, @receiver
|
|
159
|
-
receiver.shutdown
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def run_control_io
|
|
163
|
-
@control_read = Coolio::IO.new(IO.new(@control_read_fd))
|
|
154
|
+
def run_worker_process_agent
|
|
155
|
+
input = IO.new(@control_read_fd)
|
|
164
156
|
@control_read_fd = nil
|
|
165
|
-
|
|
166
|
-
line_buffer = LineBuffer.new
|
|
167
|
-
line_buffer.feed(data) do |line|
|
|
168
|
-
case line
|
|
169
|
-
when Messages::STOP_GRACEFUL
|
|
170
|
-
stop_gracefully
|
|
171
|
-
when Messages::STOP_IMMEDIATELY
|
|
172
|
-
stop_immediately
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
@control_read.on_read do |data|
|
|
177
|
-
on_read.call(data)
|
|
178
|
-
end
|
|
179
|
-
read_on_close = lambda do
|
|
180
|
-
if @control_read
|
|
181
|
-
@control_read = nil
|
|
182
|
-
stop_immediately
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
@control_read.on_close do
|
|
186
|
-
read_on_close.call
|
|
187
|
-
end
|
|
188
|
-
@loop.attach(@control_read)
|
|
189
|
-
|
|
190
|
-
@control_write = Coolio::IO.new(IO.new(@control_write_fd))
|
|
157
|
+
output = IO.new(@control_write_fd)
|
|
191
158
|
@control_write_fd = nil
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
stop_immediately
|
|
196
|
-
end
|
|
197
|
-
@control_write_closed = true
|
|
159
|
+
@worker_process_agent = WorkerProcessAgent.new(@loop, input, output)
|
|
160
|
+
@worker_process_agent.on_stop_gracefully = lambda do
|
|
161
|
+
stop_gracefully
|
|
198
162
|
end
|
|
199
|
-
@
|
|
200
|
-
|
|
163
|
+
@worker_process_agent.on_stop_immediately = lambda do
|
|
164
|
+
stop_immediately
|
|
201
165
|
end
|
|
202
|
-
@
|
|
203
|
-
|
|
204
|
-
@control_write.write(Messages::READY)
|
|
166
|
+
@worker_process_agent.start
|
|
205
167
|
end
|
|
206
168
|
|
|
207
|
-
def
|
|
208
|
-
|
|
209
|
-
@control_write, control_write = nil, @control_write
|
|
210
|
-
control_write.detach
|
|
211
|
-
end
|
|
212
|
-
if @control_read
|
|
213
|
-
@control_read, control_read = nil, @control_read
|
|
214
|
-
control_read.close
|
|
215
|
-
end
|
|
169
|
+
def shutdown_worker_process_agent
|
|
170
|
+
@worker_process_agent.stop
|
|
216
171
|
end
|
|
217
172
|
|
|
218
173
|
def create_receiver
|
|
@@ -250,17 +205,17 @@ module Droonga
|
|
|
250
205
|
def stop_gracefully
|
|
251
206
|
return if @stopping
|
|
252
207
|
@stopping = true
|
|
253
|
-
|
|
208
|
+
@receiver.stop_gracefully
|
|
254
209
|
@engine.stop_gracefully do
|
|
255
|
-
|
|
210
|
+
shutdown_worker_process_agent
|
|
256
211
|
shutdown_internal_message_receiver
|
|
257
212
|
end
|
|
258
213
|
end
|
|
259
214
|
|
|
260
215
|
# It may be called after stop_gracefully.
|
|
261
216
|
def stop_immediately
|
|
262
|
-
|
|
263
|
-
|
|
217
|
+
shutdown_worker_process_agent
|
|
218
|
+
@receiver.stop_immediately
|
|
264
219
|
shutdown_internal_message_receiver
|
|
265
220
|
@engine.stop_immediately
|
|
266
221
|
@loop.stop
|
|
@@ -0,0 +1,232 @@
|
|
|
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 "optparse"
|
|
17
|
+
require "fileutils"
|
|
18
|
+
|
|
19
|
+
require "coolio"
|
|
20
|
+
|
|
21
|
+
require "droonga/job_receiver"
|
|
22
|
+
require "droonga/plugin_loader"
|
|
23
|
+
require "droonga/worker_process_agent"
|
|
24
|
+
require "droonga/handler_runner"
|
|
25
|
+
|
|
26
|
+
module Droonga
|
|
27
|
+
module Command
|
|
28
|
+
class DroongaEngineWorker
|
|
29
|
+
class << self
|
|
30
|
+
def run(command_line_arguments)
|
|
31
|
+
new.run(command_line_arguments)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
include Loggable
|
|
36
|
+
|
|
37
|
+
def initialize
|
|
38
|
+
@job_queue_socket_path = nil
|
|
39
|
+
@contrtol_read_fd = nil
|
|
40
|
+
@contrtol_write_fd = nil
|
|
41
|
+
@pid_file_path = nil
|
|
42
|
+
@dataset = nil
|
|
43
|
+
@database_path = nil
|
|
44
|
+
@plugins = []
|
|
45
|
+
@worker_process_agent = nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def run(command_line_arguments)
|
|
49
|
+
create_new_process_group
|
|
50
|
+
|
|
51
|
+
parse_command_line_arguments!(command_line_arguments)
|
|
52
|
+
PluginLoader.load_all
|
|
53
|
+
|
|
54
|
+
write_pid_file do
|
|
55
|
+
run_main_loop
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
def create_new_process_group
|
|
61
|
+
begin
|
|
62
|
+
Process.setsid
|
|
63
|
+
rescue SystemCallError, NotImplementedError
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def parse_command_line_arguments!(command_line_arguments)
|
|
68
|
+
parser = OptionParser.new
|
|
69
|
+
add_internal_options(parser)
|
|
70
|
+
parser.parse!(command_line_arguments)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def add_internal_options(parser)
|
|
74
|
+
parser.separator("")
|
|
75
|
+
parser.separator("Internal:")
|
|
76
|
+
parser.on("--job-queue-socket-path=PATH",
|
|
77
|
+
"Read jobs from PATH") do |path|
|
|
78
|
+
@job_queue_socket_path = Pathname.new(path)
|
|
79
|
+
end
|
|
80
|
+
parser.on("--control-read-fd=FD", Integer,
|
|
81
|
+
"Use FD to read control messages from the service") do |fd|
|
|
82
|
+
@control_read_fd = fd
|
|
83
|
+
end
|
|
84
|
+
parser.on("--control-write-fd=FD", Integer,
|
|
85
|
+
"Use FD to write control messages from the service") do |fd|
|
|
86
|
+
@control_write_fd = fd
|
|
87
|
+
end
|
|
88
|
+
parser.on("--pid-file=PATH",
|
|
89
|
+
"Put PID to PATH") do |path|
|
|
90
|
+
@pid_file_path = Pathname.new(path)
|
|
91
|
+
end
|
|
92
|
+
parser.on("--dataset=DATASET",
|
|
93
|
+
"Process DATASET") do |dataset|
|
|
94
|
+
@dataset = dataset
|
|
95
|
+
end
|
|
96
|
+
parser.on("--database-path=PATH",
|
|
97
|
+
"Use database at PATH") do |path|
|
|
98
|
+
@database_path = Pathname.new(path)
|
|
99
|
+
end
|
|
100
|
+
parser.on("--plugins=PLUGIN1,PLUGIN2,...", Array,
|
|
101
|
+
"Use PLUGINs") do |plugins|
|
|
102
|
+
@plugins = plugins
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def write_pid_file
|
|
107
|
+
if @pid_file_path
|
|
108
|
+
@pid_file_path.open("w") do |file|
|
|
109
|
+
file.puts(Process.pid)
|
|
110
|
+
end
|
|
111
|
+
begin
|
|
112
|
+
yield
|
|
113
|
+
ensure
|
|
114
|
+
FileUtils.rm_f(@pid_file_path.to_s)
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
yield
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def run_main_loop
|
|
122
|
+
begin
|
|
123
|
+
start
|
|
124
|
+
true
|
|
125
|
+
rescue
|
|
126
|
+
logger.exception("failed while running", $!)
|
|
127
|
+
false
|
|
128
|
+
ensure
|
|
129
|
+
stop_worker_process_agent
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def start
|
|
134
|
+
@stopping = false
|
|
135
|
+
@loop = Coolio::Loop.default
|
|
136
|
+
|
|
137
|
+
start_forwarder
|
|
138
|
+
start_handler_runner
|
|
139
|
+
start_job_receiver
|
|
140
|
+
start_worker_process_agent
|
|
141
|
+
|
|
142
|
+
@loop.run
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def stop_gracefully
|
|
146
|
+
return if @stopping
|
|
147
|
+
@stopping = true
|
|
148
|
+
|
|
149
|
+
stop_worker_process_agent
|
|
150
|
+
stop_job_receiver
|
|
151
|
+
stop_handler_runner
|
|
152
|
+
stop_forwarder
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# It may be called after stop_gracefully.
|
|
156
|
+
def stop_immediately
|
|
157
|
+
stop_gracefully
|
|
158
|
+
@loop.stop
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def start_forwarder
|
|
162
|
+
@forwarder = Forwarder.new(@loop)
|
|
163
|
+
@forwarder.start
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def stop_forwarder
|
|
167
|
+
@forwarder.shutdown
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def start_handler_runner
|
|
171
|
+
options = {
|
|
172
|
+
:forwarder => @forwarder,
|
|
173
|
+
:dataset => @dataset,
|
|
174
|
+
:database => @database_path.to_s,
|
|
175
|
+
:plugins => @plugins,
|
|
176
|
+
}
|
|
177
|
+
@handler_runner = HandlerRunner.new(@loop, options)
|
|
178
|
+
@handler_runner.start
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def stop_handler_runner
|
|
182
|
+
@handler_runner.shutdown
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def start_job_receiver
|
|
186
|
+
@job_receiver = create_job_receiver
|
|
187
|
+
@job_receiver.start
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def create_job_receiver
|
|
191
|
+
JobReceiver.new(@loop, @job_queue_socket_path.to_s) do |message|
|
|
192
|
+
process(message)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def process(message)
|
|
197
|
+
logger.trace("process: start")
|
|
198
|
+
@handler_runner.process(message)
|
|
199
|
+
logger.trace("process: done")
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def stop_job_receiver
|
|
203
|
+
@job_receiver.shutdown
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def start_worker_process_agent
|
|
207
|
+
input = IO.new(@control_read_fd)
|
|
208
|
+
@control_read_fd = nil
|
|
209
|
+
output = IO.new(@control_write_fd)
|
|
210
|
+
@control_write_fd = nil
|
|
211
|
+
@worker_process_agent = WorkerProcessAgent.new(@loop, input, output)
|
|
212
|
+
@worker_process_agent.on_stop_gracefully = lambda do
|
|
213
|
+
stop_gracefully
|
|
214
|
+
end
|
|
215
|
+
@worker_process_agent.on_stop_immediately = lambda do
|
|
216
|
+
stop_immediately
|
|
217
|
+
end
|
|
218
|
+
@worker_process_agent.start
|
|
219
|
+
@worker_process_agent.ready
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def stop_worker_process_agent
|
|
223
|
+
return if @worker_process_agent.nil?
|
|
224
|
+
@worker_process_agent.stop
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def log_tag
|
|
228
|
+
"[#{Process.ppid}] worker"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|