fluent-plugin-droonga 0.0.2 → 0.7.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/.gitignore +6 -0
- data/.yardopts +7 -0
- data/Gemfile +14 -2
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +27 -5
- data/benchmark/benchmark.rb +1 -1
- data/benchmark/utils.rb +9 -6
- data/benchmark/watch/benchmark-notify.rb +2 -2
- data/benchmark/watch/benchmark-publish.rb +1 -1
- data/benchmark/watch/benchmark-scan.rb +1 -1
- data/benchmark/watch/catalog.json +1 -1
- data/bin/grn2jsons +1 -1
- data/fluent-plugin-droonga.gemspec +5 -3
- data/lib/droonga/adapter.rb +13 -130
- data/lib/droonga/adapter_plugin.rb +51 -0
- data/lib/droonga/catalog.rb +2 -2
- data/lib/droonga/collector.rb +107 -0
- data/lib/droonga/collector_plugin.rb +82 -0
- data/lib/droonga/command_mapper.rb +1 -1
- data/lib/droonga/{proxy.rb → dispatcher.rb} +116 -151
- data/lib/droonga/distributor.rb +51 -0
- data/lib/droonga/distributor_plugin.rb +59 -0
- data/lib/droonga/engine.rb +9 -50
- data/lib/droonga/farm.rb +47 -0
- data/lib/droonga/forwarder.rb +125 -0
- data/lib/droonga/handler.rb +69 -60
- data/lib/droonga/handler_plugin.rb +22 -11
- data/lib/droonga/input_message.rb +51 -0
- data/lib/droonga/job_queue.rb +5 -1
- data/lib/droonga/job_queue_schema.rb +1 -1
- data/lib/droonga/logger.rb +1 -1
- data/lib/droonga/partition.rb +76 -0
- data/lib/droonga/pluggable.rb +62 -0
- data/lib/droonga/plugin.rb +18 -16
- data/lib/droonga/plugin/{adapter_groonga.rb → adapter/groonga.rb} +10 -10
- data/lib/droonga/plugin/adapter/groonga/select.rb +13 -4
- data/lib/droonga/plugin/collector/basic.rb +142 -0
- data/lib/droonga/plugin/distributor/crud.rb +43 -0
- data/lib/droonga/plugin/distributor/groonga.rb +37 -0
- data/lib/droonga/plugin/distributor/search.rb +273 -0
- data/lib/droonga/plugin/distributor/watch.rb +39 -0
- data/lib/droonga/plugin/{handler_add.rb → handler/add.rb} +6 -6
- data/lib/droonga/plugin/{handler_forward.rb → handler/forward.rb} +9 -4
- data/lib/droonga/plugin/{handler_groonga.rb → handler/groonga.rb} +36 -4
- data/lib/droonga/plugin/handler/groonga/column_create.rb +5 -9
- data/lib/droonga/plugin/handler/groonga/table_create.rb +9 -18
- data/lib/droonga/plugin/{handler_search.rb → handler/search.rb} +4 -4
- data/lib/droonga/plugin/{handler_watch.rb → handler/watch.rb} +4 -4
- data/lib/droonga/plugin_loader.rb +45 -0
- data/lib/droonga/plugin_registerable.rb +51 -0
- data/lib/droonga/plugin_repository.rb +56 -0
- data/lib/droonga/processor.rb +64 -0
- data/lib/droonga/searcher.rb +16 -7
- data/lib/droonga/server.rb +5 -9
- data/lib/droonga/sweeper.rb +1 -1
- data/lib/droonga/watch_schema.rb +1 -1
- data/lib/droonga/watcher.rb +1 -1
- data/lib/droonga/worker.rb +21 -9
- data/lib/fluent/plugin/out_droonga.rb +33 -15
- data/lib/groonga_command_converter.rb +1 -1
- data/sample/cluster/fluentd.conf +0 -1
- data/test/command/config/default/catalog.json +43 -0
- data/test/command/config/default/fluentd.conf +11 -0
- data/test/command/fixture/documents.jsons +208 -0
- data/test/command/fixture/user-table-array.jsons +38 -0
- data/test/command/fixture/user-table.jsons +38 -0
- data/test/command/run-test.rb +35 -0
- data/test/command/suite/add/minimum.expected +12 -0
- data/test/command/suite/add/minimum.test +11 -0
- data/test/command/suite/add/with-values.expected +12 -0
- data/test/command/suite/add/with-values.test +17 -0
- data/test/command/suite/add/without-key.expected +12 -0
- data/test/command/suite/add/without-key.test +16 -0
- data/test/command/suite/groonga/column_create/scalar.expected +34 -0
- data/test/command/suite/groonga/column_create/scalar.test +17 -0
- data/test/command/suite/groonga/column_create/vector.expected +34 -0
- data/test/command/suite/groonga/column_create/vector.test +18 -0
- data/test/command/suite/groonga/select/minimum.expected +26 -0
- data/test/command/suite/groonga/select/minimum.test +8 -0
- data/test/command/suite/groonga/table_create/array.expected +17 -0
- data/test/command/suite/groonga/table_create/array.test +8 -0
- data/test/command/suite/groonga/table_create/hash.expected +17 -0
- data/test/command/suite/groonga/table_create/hash.test +8 -0
- data/test/command/suite/search/array-attribute-label.expected +25 -0
- data/test/command/suite/search/array-attribute-label.test +30 -0
- data/test/command/suite/search/chained-queries.expected +45 -0
- data/test/command/suite/search/chained-queries.test +43 -0
- data/test/command/suite/search/complex.expected +52 -0
- data/test/command/suite/search/complex.test +25 -0
- data/test/command/suite/search/condition-nested.expected +19 -0
- data/test/command/suite/search/condition-nested.test +29 -0
- data/test/command/suite/search/condition-query.expected +28 -0
- data/test/command/suite/search/condition-query.test +25 -0
- data/test/command/suite/search/condition-script.expected +28 -0
- data/test/command/suite/search/condition-script.test +28 -0
- data/test/command/suite/search/hash-attribute-label.expected +34 -0
- data/test/command/suite/search/hash-attribute-label.test +38 -0
- data/test/command/suite/search/minimum.expected +13 -0
- data/test/command/suite/search/minimum.test +16 -0
- data/test/command/suite/search/multiple-queries.expected +39 -0
- data/test/command/suite/search/multiple-queries.test +39 -0
- data/test/command/suite/search/output-range.expected +28 -0
- data/test/command/suite/search/output-range.test +25 -0
- data/test/command/suite/search/simple.expected +52 -0
- data/test/command/suite/search/simple.test +24 -0
- data/test/command/suite/search/sort-and-output-range.expected +25 -0
- data/test/command/suite/search/sort-and-output-range.test +29 -0
- data/test/command/suite/search/sort-range.expected +28 -0
- data/test/command/suite/search/sort-range.test +28 -0
- data/test/command/suite/search/sort-with-invisible-column.expected +28 -0
- data/test/command/suite/search/sort-with-invisible-column.test +28 -0
- data/test/unit/fixtures/array.grn +18 -0
- data/test/{fixtures → unit/fixtures}/catalog.json +0 -0
- data/test/{fixtures → unit/fixtures}/document.grn +20 -9
- data/test/unit/fixtures/reference/array.grn +11 -0
- data/test/unit/fixtures/reference/hash.grn +7 -0
- data/test/{helper.rb → unit/helper.rb} +2 -1
- data/test/{helper → unit/helper}/fixture.rb +1 -1
- data/test/unit/helper/plugin_helper.rb +38 -0
- data/test/{helper → unit/helper}/sandbox.rb +19 -6
- data/test/{helper → unit/helper}/stub_worker.rb +1 -1
- data/test/{helper → unit/helper}/watch_helper.rb +1 -13
- data/test/{plugin → unit/plugin}/adapter/groonga/test_select.rb +108 -4
- data/test/unit/plugin/collector/test_basic.rb +558 -0
- data/test/unit/plugin/distributor/test_search.rb +914 -0
- data/test/{plugin → unit/plugin}/handler/groonga/test_column_create.rb +18 -14
- data/test/{plugin → unit/plugin}/handler/groonga/test_table_create.rb +13 -11
- data/test/{plugin/handler/test_handler_add.rb → unit/plugin/handler/test_add.rb} +2 -14
- data/test/{plugin/handler/test_handler_groonga.rb → unit/plugin/handler/test_groonga.rb} +6 -26
- data/test/unit/plugin/handler/test_search.rb +601 -0
- data/test/{plugin/handler/test_handler_watch.rb → unit/plugin/handler/test_watch.rb} +2 -2
- data/test/{run-test.rb → unit/run-test.rb} +3 -3
- data/test/{test_adapter.rb → unit/test_adapter.rb} +17 -14
- data/test/{test_catalog.rb → unit/test_catalog.rb} +4 -4
- data/test/{test_command_mapper.rb → unit/test_command_mapper.rb} +1 -1
- data/test/{test_groonga_command_converter.rb → unit/test_groonga_command_converter.rb} +3 -3
- data/test/{test_job_queue_schema.rb → unit/test_job_queue_schema.rb} +1 -1
- data/test/{test_output.rb → unit/test_output.rb} +9 -9
- data/test/{test_handler.rb → unit/test_plugin.rb} +19 -22
- data/test/unit/test_plugin_repository.rb +89 -0
- data/test/{test_sweeper.rb → unit/test_sweeper.rb} +1 -1
- data/test/{test_watch_schema.rb → unit/test_watch_schema.rb} +1 -1
- data/test/{test_watcher.rb → unit/test_watcher.rb} +1 -1
- metadata +226 -66
- data/lib/droonga/executor.rb +0 -289
- data/lib/droonga/plugin/handler_proxy.rb +0 -82
- data/test/plugin/handler/test_handler_search.rb +0 -512
- data/test/test_worker.rb +0 -144
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
8
|
+
#
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
15
|
+
# License along with this library; if not, write to the Free Software
|
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/pluggable"
|
|
19
|
+
require "droonga/distributor_plugin"
|
|
20
|
+
|
|
21
|
+
module Droonga
|
|
22
|
+
class Distributor
|
|
23
|
+
include Pluggable
|
|
24
|
+
|
|
25
|
+
def initialize(dispatcher, options={})
|
|
26
|
+
@dispatcher = dispatcher
|
|
27
|
+
@plugins = []
|
|
28
|
+
@options = options
|
|
29
|
+
# TODO: don't put the default distributions
|
|
30
|
+
load_plugins(options[:distributors] || ["search", "crud", "groonga", "watch"])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def distribute(envelope)
|
|
34
|
+
command = envelope["type"]
|
|
35
|
+
process(command, envelope)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def post(message)
|
|
39
|
+
@dispatcher.handle(message, [])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
def instantiate_plugin(name)
|
|
44
|
+
DistributorPlugin.repository.instantiate(name, self)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def log_tag
|
|
48
|
+
"[#{Process.pid}] distributor"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
8
|
+
#
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
15
|
+
# License along with this library; if not, write to the Free Software
|
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/plugin"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class DistributorPlugin < Plugin
|
|
22
|
+
extend PluginRegisterable
|
|
23
|
+
|
|
24
|
+
def initialize(distributor)
|
|
25
|
+
super()
|
|
26
|
+
@distributor = distributor
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# TODO: consider better name
|
|
30
|
+
def post(message)
|
|
31
|
+
@distributor.post(message)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def scatter_all(envelope, key)
|
|
35
|
+
message = [{
|
|
36
|
+
"command"=> envelope["type"],
|
|
37
|
+
"dataset"=> envelope["dataset"],
|
|
38
|
+
"body"=> envelope["body"],
|
|
39
|
+
"key"=> key,
|
|
40
|
+
"type"=> "scatter",
|
|
41
|
+
"replica"=> "all",
|
|
42
|
+
"post"=> true
|
|
43
|
+
}]
|
|
44
|
+
post(message)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def broadcast_all(envelope)
|
|
48
|
+
distirubte_message = [{
|
|
49
|
+
"command"=> envelope["type"],
|
|
50
|
+
"dataset"=> envelope["dataset"],
|
|
51
|
+
"body"=> envelope["body"],
|
|
52
|
+
"type"=> "broadcast",
|
|
53
|
+
"replica"=> "all",
|
|
54
|
+
"post"=> true
|
|
55
|
+
}]
|
|
56
|
+
post(distirubte_message)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/droonga/engine.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2013
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
4
|
#
|
|
5
5
|
# This library is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -15,69 +15,28 @@
|
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
16
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
17
|
|
|
18
|
-
require "
|
|
19
|
-
require "
|
|
20
|
-
require "cool.io"
|
|
21
|
-
|
|
22
|
-
require "droonga/server"
|
|
23
|
-
require "droonga/worker"
|
|
24
|
-
require "droonga/executor"
|
|
18
|
+
require "droonga/logger"
|
|
19
|
+
require "droonga/dispatcher"
|
|
25
20
|
|
|
26
21
|
module Droonga
|
|
27
22
|
class Engine
|
|
28
|
-
DEFAULT_OPTIONS = {
|
|
29
|
-
:queue_name => "DroongaQueue",
|
|
30
|
-
:n_workers => 0,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
23
|
def initialize(options={})
|
|
34
|
-
@options =
|
|
24
|
+
@options = options
|
|
25
|
+
@dispatcher = Dispatcher.new(@options)
|
|
35
26
|
end
|
|
36
27
|
|
|
37
28
|
def start
|
|
38
|
-
|
|
39
|
-
Droonga::JobQueue.ensure_schema(@options[:database],
|
|
40
|
-
@options[:queue_name])
|
|
41
|
-
end
|
|
42
|
-
start_supervisor if @options[:n_workers] > 0
|
|
43
|
-
@executor = Executor.new(@options)
|
|
29
|
+
@dispatcher.start
|
|
44
30
|
end
|
|
45
31
|
|
|
46
32
|
def shutdown
|
|
47
33
|
$log.trace("engine: shutdown: start")
|
|
48
|
-
@
|
|
49
|
-
shutdown_supervisor if @supervisor
|
|
34
|
+
@dispatcher.shutdown
|
|
50
35
|
$log.trace("engine: shutdown: done")
|
|
51
36
|
end
|
|
52
37
|
|
|
53
|
-
def
|
|
54
|
-
|
|
55
|
-
@executor.dispatch(tag, time, record, synchronous)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
private
|
|
59
|
-
def start_supervisor
|
|
60
|
-
@supervisor = ServerEngine::Supervisor.new(Server, Worker) do
|
|
61
|
-
force_options = {
|
|
62
|
-
:worker_type => "process",
|
|
63
|
-
:workers => @options[:n_workers],
|
|
64
|
-
:log_level => $log.level,
|
|
65
|
-
:server_process_name => "Server[#{@options[:database]}] #$0",
|
|
66
|
-
:worker_process_name => "Worker[#{@options[:database]}] #$0"
|
|
67
|
-
}
|
|
68
|
-
@options.merge(force_options)
|
|
69
|
-
end
|
|
70
|
-
@supervisor_thread = Thread.new do
|
|
71
|
-
@supervisor.main
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def shutdown_supervisor
|
|
76
|
-
$log.trace("supervisor: shutdown: start")
|
|
77
|
-
@supervisor.stop(true)
|
|
78
|
-
$log.trace("supervisor: shutdown: stopped")
|
|
79
|
-
@supervisor_thread.join
|
|
80
|
-
$log.trace("supervisor: shutdown: done")
|
|
38
|
+
def process(envelope)
|
|
39
|
+
@dispatcher.handle_envelope(envelope)
|
|
81
40
|
end
|
|
82
41
|
end
|
|
83
42
|
end
|
data/lib/droonga/farm.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
8
|
+
#
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
15
|
+
# License along with this library; if not, write to the Free Software
|
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "droonga/partition"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class Farm
|
|
22
|
+
def initialize(name)
|
|
23
|
+
@name = name
|
|
24
|
+
@partitions = {}
|
|
25
|
+
Droonga.catalog.get_partitions(name).each do |partition_name, options|
|
|
26
|
+
partition = Droonga::Partition.new(options)
|
|
27
|
+
@partitions[partition_name] = partition
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def start
|
|
32
|
+
@partitions.each_value do |partition|
|
|
33
|
+
partition.start
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def shutdown
|
|
38
|
+
@partitions.each_value do |partition|
|
|
39
|
+
partition.shutdown
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def process(partition_name, envelope, synchronous)
|
|
44
|
+
@partitions[partition_name].process(envelope, synchronous)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
|
+
#
|
|
5
|
+
# This library is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
7
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
8
|
+
#
|
|
9
|
+
# This library is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
12
|
+
# Lesser General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
15
|
+
# License along with this library; if not, write to the Free Software
|
|
16
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
|
+
|
|
18
|
+
require "fluent-logger"
|
|
19
|
+
require "fluent/logger/fluent_logger"
|
|
20
|
+
|
|
21
|
+
module Droonga
|
|
22
|
+
class Forwarder
|
|
23
|
+
def initialize
|
|
24
|
+
@outputs = {}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def shutdown
|
|
28
|
+
$log.trace("#{log_tag}: shutdown: start")
|
|
29
|
+
@outputs.each do |dest, output|
|
|
30
|
+
output[:logger].close if output[:logger]
|
|
31
|
+
end
|
|
32
|
+
$log.trace("#{log_tag}: shutdown: done")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def forward(envelope, body, destination)
|
|
36
|
+
$log.trace("#{log_tag}: post: start")
|
|
37
|
+
command = destination["type"]
|
|
38
|
+
receiver = destination["to"]
|
|
39
|
+
arguments = destination["arguments"]
|
|
40
|
+
output(receiver, envelope, body, command, arguments)
|
|
41
|
+
$log.trace("#{log_tag}: post: done")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
def output(receiver, envelope, body, command, arguments)
|
|
46
|
+
$log.trace("#{log_tag}: output: start")
|
|
47
|
+
unless receiver.is_a?(String) && command.is_a?(String)
|
|
48
|
+
$log.trace("#{log_tag}: output: abort: invalid argument",
|
|
49
|
+
:receiver => receiver,
|
|
50
|
+
:command => command)
|
|
51
|
+
return
|
|
52
|
+
end
|
|
53
|
+
unless receiver =~ /\A(.*):(\d+)\/(.*?)(\?.+)?\z/
|
|
54
|
+
raise "format: hostname:port/tag(?params)"
|
|
55
|
+
end
|
|
56
|
+
host = $1
|
|
57
|
+
port = $2
|
|
58
|
+
tag = $3
|
|
59
|
+
params = $4
|
|
60
|
+
output = get_output(host, port, params)
|
|
61
|
+
unless output
|
|
62
|
+
$log.trace("#{log_tag}: output: abort: no output",
|
|
63
|
+
:host => host,
|
|
64
|
+
:port => port,
|
|
65
|
+
:params => params)
|
|
66
|
+
return
|
|
67
|
+
end
|
|
68
|
+
if command =~ /\.result$/
|
|
69
|
+
message = {
|
|
70
|
+
inReplyTo: envelope["id"],
|
|
71
|
+
statusCode: 200,
|
|
72
|
+
type: command,
|
|
73
|
+
body: body
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
message = envelope.merge(
|
|
77
|
+
body: body,
|
|
78
|
+
type: command,
|
|
79
|
+
arguments: arguments
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
output_tag = "#{tag}.message"
|
|
83
|
+
log_info = "<#{receiver}>:<#{output_tag}>"
|
|
84
|
+
$log.trace("#{log_tag}: output: post: start: #{log_info}")
|
|
85
|
+
output.post(output_tag, message)
|
|
86
|
+
$log.trace("#{log_tag}: output: post: done: #{log_info}")
|
|
87
|
+
$log.trace("#{log_tag}: output: done")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def get_output(host, port, params)
|
|
91
|
+
host_port = "#{host}:#{port}"
|
|
92
|
+
@outputs[host_port] ||= {}
|
|
93
|
+
output = @outputs[host_port]
|
|
94
|
+
|
|
95
|
+
has_connection_id = (not params.nil? \
|
|
96
|
+
and params =~ /[\?&;]connection_id=([^&;]+)/)
|
|
97
|
+
if output[:logger].nil? or has_connection_id
|
|
98
|
+
connection_id = $1
|
|
99
|
+
if not has_connection_id or output[:connection_id] != connection_id
|
|
100
|
+
output[:connection_id] = connection_id
|
|
101
|
+
logger = create_logger(:host => host, :port => port.to_i)
|
|
102
|
+
# output[:logger] should be closed if it exists beforehand?
|
|
103
|
+
output[:logger] = logger
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
has_client_session_id = (not params.nil? \
|
|
108
|
+
and params =~ /[\?&;]client_session_id=([^&;]+)/)
|
|
109
|
+
if has_client_session_id
|
|
110
|
+
client_session_id = $1
|
|
111
|
+
# some generic way to handle client_session_id is expected
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
output[:logger]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def create_logger(options)
|
|
118
|
+
Fluent::Logger::FluentLogger.new(nil, options)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def log_tag
|
|
122
|
+
"[#{Process.ppid}][#{Process.pid}] forwarder"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
data/lib/droonga/handler.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2013
|
|
3
|
+
# Copyright (C) 2013 Droonga Project
|
|
4
4
|
#
|
|
5
5
|
# This library is free software; you can redistribute it and/or
|
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
|
@@ -15,75 +15,52 @@
|
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
|
16
16
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
17
17
|
|
|
18
|
+
require "groonga"
|
|
19
|
+
|
|
20
|
+
require "droonga/forwarder"
|
|
21
|
+
require "droonga/pluggable"
|
|
18
22
|
require "droonga/handler_plugin"
|
|
19
|
-
require "droonga/command_mapper"
|
|
20
|
-
require "droonga/logger"
|
|
21
23
|
|
|
22
24
|
module Droonga
|
|
23
25
|
class Handler
|
|
24
|
-
|
|
25
|
-
def inherited(sub_class)
|
|
26
|
-
super
|
|
27
|
-
sub_class.instance_variable_set(:@command_mapper, CommandMapper.new)
|
|
28
|
-
end
|
|
26
|
+
include Pluggable
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
@command_mapper.register(name_or_map)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def method_name(command)
|
|
35
|
-
@command_mapper[command]
|
|
36
|
-
end
|
|
28
|
+
attr_reader :context, :envelope, :name
|
|
37
29
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def initialize(worker)
|
|
44
|
-
@worker = worker
|
|
45
|
-
@context = @worker.context
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def post(body, destination=nil)
|
|
49
|
-
@worker.post(body, destination)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def envelope
|
|
53
|
-
@worker.envelope
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def add_route(route)
|
|
57
|
-
@worker.add_route(route)
|
|
30
|
+
def initialize(options={})
|
|
31
|
+
@options = options
|
|
32
|
+
@name = options[:name]
|
|
33
|
+
@database_name = options[:database]
|
|
34
|
+
prepare
|
|
58
35
|
end
|
|
59
36
|
|
|
60
37
|
def shutdown
|
|
38
|
+
$log.trace("#{log_tag}: shutdown: start")
|
|
39
|
+
super
|
|
40
|
+
@forwarder.shutdown
|
|
41
|
+
if @database
|
|
42
|
+
@database.close
|
|
43
|
+
@context.close
|
|
44
|
+
@database = @context = nil
|
|
45
|
+
end
|
|
46
|
+
$log.trace("#{log_tag}: shutdown: done")
|
|
61
47
|
end
|
|
62
48
|
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def invoke(command, request, *arguments)
|
|
68
|
-
__send__(self.class.method_name(command), request, *arguments)
|
|
69
|
-
rescue => exception
|
|
70
|
-
Logger.error("error while handling #{command}",
|
|
71
|
-
request: request,
|
|
72
|
-
arguments: arguments,
|
|
73
|
-
exception: exception)
|
|
49
|
+
def prefer_synchronous?(command)
|
|
50
|
+
find_plugin(command).prefer_synchronous?(command)
|
|
74
51
|
end
|
|
75
52
|
|
|
76
|
-
def
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
53
|
+
def process(envelope)
|
|
54
|
+
$log.trace("#{log_tag}: process: start")
|
|
55
|
+
body, command, arguments = parse_envelope(envelope)
|
|
56
|
+
plugin = find_plugin(command)
|
|
57
|
+
if plugin.nil?
|
|
58
|
+
$log.trace("#{log_tag}: process: done: no plugin: <#{command}>")
|
|
59
|
+
return
|
|
82
60
|
end
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return false
|
|
61
|
+
process_command(plugin, command, body, arguments)
|
|
62
|
+
$log.trace("#{log_tag}: process: done: <#{command}>",
|
|
63
|
+
:plugin => plugin.class)
|
|
87
64
|
end
|
|
88
65
|
|
|
89
66
|
def emit(value, name = nil)
|
|
@@ -98,7 +75,31 @@ module Droonga
|
|
|
98
75
|
@output_values[name] = value
|
|
99
76
|
end
|
|
100
77
|
|
|
101
|
-
def
|
|
78
|
+
def post(message, destination)
|
|
79
|
+
@forwarder.forward(envelope, message, destination)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
def parse_envelope(envelope)
|
|
84
|
+
@envelope = envelope
|
|
85
|
+
envelope["via"] ||= []
|
|
86
|
+
[envelope["body"], envelope["type"], envelope["arguments"]]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def prepare
|
|
90
|
+
if @database_name && !@database_name.empty?
|
|
91
|
+
@context = Groonga::Context.new
|
|
92
|
+
@database = @context.open_database(@database_name)
|
|
93
|
+
end
|
|
94
|
+
load_plugins(@options[:handlers] || [])
|
|
95
|
+
@forwarder = Forwarder.new
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def instantiate_plugin(name)
|
|
99
|
+
HandlerPlugin.repository.instantiate(name, self)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def process_command(plugin, command, request, arguments)
|
|
102
103
|
return false unless request.is_a? Hash
|
|
103
104
|
|
|
104
105
|
@task = request["task"]
|
|
@@ -115,14 +116,18 @@ module Droonga
|
|
|
115
116
|
@input_name = request["name"]
|
|
116
117
|
@descendants = request["descendants"]
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
plugin.process(command, @body, *arguments)
|
|
119
120
|
output if @descendants
|
|
120
121
|
true
|
|
121
122
|
end
|
|
122
123
|
|
|
123
124
|
def output
|
|
124
125
|
result = @task["values"]
|
|
125
|
-
|
|
126
|
+
if @component["post"]
|
|
127
|
+
destination = @component["post"]
|
|
128
|
+
destination = envelope["replyTo"] if destination == true
|
|
129
|
+
post(result, destination)
|
|
130
|
+
end
|
|
126
131
|
@descendants.each do |name, dests|
|
|
127
132
|
message = {
|
|
128
133
|
"id" => @id,
|
|
@@ -131,10 +136,14 @@ module Droonga
|
|
|
131
136
|
}
|
|
132
137
|
dests.each do |routes|
|
|
133
138
|
routes.each do |route|
|
|
134
|
-
post(message, "to"=>route, "type"=>"
|
|
139
|
+
post(message, "to"=>route, "type"=>"dispatcher")
|
|
135
140
|
end
|
|
136
141
|
end
|
|
137
142
|
end
|
|
138
143
|
end
|
|
144
|
+
|
|
145
|
+
def log_tag
|
|
146
|
+
"[#{Process.ppid}][#{Process.pid}] handler"
|
|
147
|
+
end
|
|
139
148
|
end
|
|
140
149
|
end
|