droonga-engine 1.0.1
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.
- data/.dir-locals.el +3 -0
- data/.gitignore +6 -0
- data/.travis.yml +15 -0
- data/.yardopts +7 -0
- data/Gemfile +66 -0
- data/LICENSE.txt +14 -0
- data/README.md +17 -0
- data/Rakefile +64 -0
- data/benchmark/benchmark.rb +123 -0
- data/benchmark/utils.rb +246 -0
- data/benchmark/watch/benchmark-notify.rb +143 -0
- data/benchmark/watch/benchmark-notify.sh +20 -0
- data/benchmark/watch/benchmark-publish.rb +120 -0
- data/benchmark/watch/benchmark-scan.rb +213 -0
- data/bin/droonga-catalog-generate +103 -0
- data/bin/droonga-engine +20 -0
- data/bin/droonga-engine-service +20 -0
- data/doc/text/news.md +106 -0
- data/droonga-engine.gemspec +52 -0
- data/lib/droonga/adapter.rb +48 -0
- data/lib/droonga/adapter_runner.rb +104 -0
- data/lib/droonga/catalog/base.rb +41 -0
- data/lib/droonga/catalog/collection_volume.rb +106 -0
- data/lib/droonga/catalog/dataset.rb +69 -0
- data/lib/droonga/catalog/errors.rb +113 -0
- data/lib/droonga/catalog/schema.rb +186 -0
- data/lib/droonga/catalog/single_volume.rb +28 -0
- data/lib/droonga/catalog/slice.rb +41 -0
- data/lib/droonga/catalog/version1.rb +427 -0
- data/lib/droonga/catalog/version2.rb +96 -0
- data/lib/droonga/catalog/version2_validator.rb +63 -0
- data/lib/droonga/catalog/volume.rb +33 -0
- data/lib/droonga/catalog/volume_collection.rb +56 -0
- data/lib/droonga/catalog_generator.rb +156 -0
- data/lib/droonga/catalog_loader.rb +56 -0
- data/lib/droonga/catalog_observer.rb +83 -0
- data/lib/droonga/collector.rb +38 -0
- data/lib/droonga/collector_message.rb +71 -0
- data/lib/droonga/collector_runner.rb +64 -0
- data/lib/droonga/collectors/and.rb +26 -0
- data/lib/droonga/collectors/or.rb +26 -0
- data/lib/droonga/collectors/sum.rb +26 -0
- data/lib/droonga/collectors.rb +18 -0
- data/lib/droonga/dispatcher.rb +326 -0
- data/lib/droonga/distributed_command_planner.rb +179 -0
- data/lib/droonga/distributor.rb +87 -0
- data/lib/droonga/engine/command/droonga_engine.rb +441 -0
- data/lib/droonga/engine/version.rb +20 -0
- data/lib/droonga/engine.rb +80 -0
- data/lib/droonga/engine_state.rb +79 -0
- data/lib/droonga/error.rb +73 -0
- data/lib/droonga/error_messages.rb +33 -0
- data/lib/droonga/event_loop.rb +46 -0
- data/lib/droonga/farm.rb +58 -0
- data/lib/droonga/fluent_message_receiver.rb +191 -0
- data/lib/droonga/fluent_message_sender.rb +140 -0
- data/lib/droonga/forwarder.rb +119 -0
- data/lib/droonga/handler.rb +49 -0
- data/lib/droonga/handler_message.rb +61 -0
- data/lib/droonga/handler_messenger.rb +119 -0
- data/lib/droonga/handler_runner.rb +125 -0
- data/lib/droonga/input_message.rb +51 -0
- data/lib/droonga/job_protocol.rb +20 -0
- data/lib/droonga/job_pusher.rb +179 -0
- data/lib/droonga/job_receiver.rb +70 -0
- data/lib/droonga/loggable.rb +29 -0
- data/lib/droonga/logger.rb +142 -0
- data/lib/droonga/message_matcher.rb +109 -0
- data/lib/droonga/output_message.rb +55 -0
- data/lib/droonga/planner.rb +47 -0
- data/lib/droonga/pluggable.rb +31 -0
- data/lib/droonga/plugin/metadata/adapter_input_message.rb +39 -0
- data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
- data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
- data/lib/droonga/plugin/metadata/handler_action.rb +39 -0
- data/lib/droonga/plugin/metadata/input_message.rb +54 -0
- data/lib/droonga/plugin.rb +43 -0
- data/lib/droonga/plugin_loader.rb +63 -0
- data/lib/droonga/plugin_registry.rb +66 -0
- data/lib/droonga/plugins/basic.rb +54 -0
- data/lib/droonga/plugins/crud.rb +145 -0
- data/lib/droonga/plugins/dump.rb +97 -0
- data/lib/droonga/plugins/error.rb +51 -0
- data/lib/droonga/plugins/groonga/column_create.rb +123 -0
- data/lib/droonga/plugins/groonga/column_list.rb +124 -0
- data/lib/droonga/plugins/groonga/column_remove.rb +65 -0
- data/lib/droonga/plugins/groonga/column_rename.rb +67 -0
- data/lib/droonga/plugins/groonga/delete.rb +117 -0
- data/lib/droonga/plugins/groonga/generic_command.rb +105 -0
- data/lib/droonga/plugins/groonga/generic_response.rb +43 -0
- data/lib/droonga/plugins/groonga/select.rb +236 -0
- data/lib/droonga/plugins/groonga/table_create.rb +111 -0
- data/lib/droonga/plugins/groonga/table_list.rb +120 -0
- data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
- data/lib/droonga/plugins/groonga.rb +37 -0
- data/lib/droonga/plugins/search/distributed_search_planner.rb +407 -0
- data/lib/droonga/plugins/search.rb +146 -0
- data/lib/droonga/plugins/watch.rb +178 -0
- data/lib/droonga/processor.rb +63 -0
- data/lib/droonga/reducer.rb +169 -0
- data/lib/droonga/replier.rb +49 -0
- data/lib/droonga/schema_applier.rb +167 -0
- data/lib/droonga/searcher/mecab_filter.rb +67 -0
- data/lib/droonga/searcher.rb +733 -0
- data/lib/droonga/server.rb +45 -0
- data/lib/droonga/session.rb +99 -0
- data/lib/droonga/single_step.rb +68 -0
- data/lib/droonga/single_step_definition.rb +54 -0
- data/lib/droonga/slice.rb +122 -0
- data/lib/droonga/status_code.rb +25 -0
- data/lib/droonga/step_runner.rb +64 -0
- data/lib/droonga/sweeper.rb +42 -0
- data/lib/droonga/test/stub_handler.rb +37 -0
- data/lib/droonga/test/stub_handler_message.rb +35 -0
- data/lib/droonga/test/stub_handler_messenger.rb +34 -0
- data/lib/droonga/test/stub_planner.rb +31 -0
- data/lib/droonga/test.rb +21 -0
- data/lib/droonga/watch_schema.rb +92 -0
- data/lib/droonga/watcher.rb +257 -0
- data/lib/droonga/worker.rb +61 -0
- data/sample/cluster/catalog.json +42 -0
- data/sample/mecab_filter/data.grn +7 -0
- data/sample/mecab_filter/ddl.grn +7 -0
- data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
- data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
- data/test/command/config/default/catalog.json +85 -0
- data/test/command/config/default/fluentd.conf +11 -0
- data/test/command/config/version1/catalog.json +68 -0
- data/test/command/config/version1/fluentd.conf +11 -0
- data/test/command/fixture/documents.jsons +208 -0
- data/test/command/fixture/event.jsons +41 -0
- data/test/command/fixture/user-table-array.jsons +38 -0
- data/test/command/fixture/user-table.jsons +47 -0
- data/test/command/run-test.rb +34 -0
- data/test/command/suite/add/dimension/column.catalog.json +28 -0
- data/test/command/suite/add/dimension/column.expected +41 -0
- data/test/command/suite/add/dimension/column.test +51 -0
- data/test/command/suite/add/dimension/integer.catalog.json +19 -0
- data/test/command/suite/add/dimension/integer.expected +41 -0
- data/test/command/suite/add/dimension/integer.test +51 -0
- data/test/command/suite/add/error/invalid-integer.expected +46 -0
- data/test/command/suite/add/error/invalid-integer.test +12 -0
- data/test/command/suite/add/error/invalid-time.expected +46 -0
- data/test/command/suite/add/error/invalid-time.test +12 -0
- data/test/command/suite/add/error/missing-key.expected +25 -0
- data/test/command/suite/add/error/missing-key.test +16 -0
- data/test/command/suite/add/error/missing-table.expected +25 -0
- data/test/command/suite/add/error/missing-table.test +16 -0
- data/test/command/suite/add/error/unknown-column.expected +46 -0
- data/test/command/suite/add/error/unknown-column.test +12 -0
- data/test/command/suite/add/error/unknown-table.expected +25 -0
- data/test/command/suite/add/error/unknown-table.test +17 -0
- data/test/command/suite/add/minimum.expected +6 -0
- data/test/command/suite/add/minimum.test +11 -0
- data/test/command/suite/add/with-values.expected +6 -0
- data/test/command/suite/add/with-values.test +17 -0
- data/test/command/suite/add/without-key.expected +6 -0
- data/test/command/suite/add/without-key.test +16 -0
- data/test/command/suite/groonga/column_create/scalar.expected +26 -0
- data/test/command/suite/groonga/column_create/scalar.test +17 -0
- data/test/command/suite/groonga/column_create/unknown-table.expected +14 -0
- data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
- data/test/command/suite/groonga/column_create/vector.expected +26 -0
- data/test/command/suite/groonga/column_create/vector.test +18 -0
- data/test/command/suite/groonga/column_list/success.expected +86 -0
- data/test/command/suite/groonga/column_list/success.test +24 -0
- data/test/command/suite/groonga/column_list/unknown-table.expected +13 -0
- data/test/command/suite/groonga/column_list/unknown-table.test +7 -0
- data/test/command/suite/groonga/column_remove/success.expected +39 -0
- data/test/command/suite/groonga/column_remove/success.test +25 -0
- data/test/command/suite/groonga/column_remove/unknown-column.expected +27 -0
- data/test/command/suite/groonga/column_remove/unknown-column.test +16 -0
- data/test/command/suite/groonga/column_remove/unknown-table.expected +14 -0
- data/test/command/suite/groonga/column_remove/unknown-table.test +7 -0
- data/test/command/suite/groonga/column_rename/success.expected +39 -0
- data/test/command/suite/groonga/column_rename/success.test +26 -0
- data/test/command/suite/groonga/column_rename/unknown-column.expected +27 -0
- data/test/command/suite/groonga/column_rename/unknown-column.test +16 -0
- data/test/command/suite/groonga/column_rename/unknown-table.expected +14 -0
- data/test/command/suite/groonga/column_rename/unknown-table.test +7 -0
- data/test/command/suite/groonga/delete/duplicated-identifiers.expected +27 -0
- data/test/command/suite/groonga/delete/duplicated-identifiers.test +17 -0
- data/test/command/suite/groonga/delete/filter.expected +19 -0
- data/test/command/suite/groonga/delete/filter.test +19 -0
- data/test/command/suite/groonga/delete/invalid-filter.expected +14 -0
- data/test/command/suite/groonga/delete/invalid-filter.test +9 -0
- data/test/command/suite/groonga/delete/no-identifier.expected +27 -0
- data/test/command/suite/groonga/delete/no-identifier.test +15 -0
- data/test/command/suite/groonga/delete/success.expected +19 -0
- data/test/command/suite/groonga/delete/success.test +19 -0
- data/test/command/suite/groonga/delete/unknown-table.expected +14 -0
- data/test/command/suite/groonga/delete/unknown-table.test +7 -0
- data/test/command/suite/groonga/select/minimum.expected +22 -0
- data/test/command/suite/groonga/select/minimum.test +8 -0
- data/test/command/suite/groonga/table_create/array.expected +14 -0
- data/test/command/suite/groonga/table_create/array.test +8 -0
- data/test/command/suite/groonga/table_create/hash.expected +13 -0
- data/test/command/suite/groonga/table_create/hash.test +8 -0
- data/test/command/suite/groonga/table_list/success.expected +71 -0
- data/test/command/suite/groonga/table_list/success.test +15 -0
- data/test/command/suite/groonga/table_remove/success.expected +13 -0
- data/test/command/suite/groonga/table_remove/success.test +8 -0
- data/test/command/suite/groonga/table_remove/unknown-table.expected +14 -0
- data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
- data/test/command/suite/message/error/missing-dataset.expected +9 -0
- data/test/command/suite/message/error/missing-dataset.test +5 -0
- data/test/command/suite/message/error/unknown-dataset.expected +9 -0
- data/test/command/suite/message/error/unknown-dataset.test +6 -0
- data/test/command/suite/message/error/unknown-type.expected +9 -0
- data/test/command/suite/message/error/unknown-type.test +6 -0
- data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
- data/test/command/suite/search/adjusters/multiple.expected +19 -0
- data/test/command/suite/search/adjusters/multiple.test +75 -0
- data/test/command/suite/search/adjusters/one.catalog.json +38 -0
- data/test/command/suite/search/adjusters/one.expected +19 -0
- data/test/command/suite/search/adjusters/one.test +66 -0
- data/test/command/suite/search/attributes/array.expected +21 -0
- data/test/command/suite/search/attributes/array.test +28 -0
- data/test/command/suite/search/attributes/hash.expected +30 -0
- data/test/command/suite/search/attributes/hash.test +36 -0
- data/test/command/suite/search/complex.expected +48 -0
- data/test/command/suite/search/complex.test +23 -0
- data/test/command/suite/search/condition/nested.expected +15 -0
- data/test/command/suite/search/condition/nested.test +27 -0
- data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +37 -0
- data/test/command/suite/search/condition/query/nonexistent_column.expected +48 -0
- data/test/command/suite/search/condition/query/nonexistent_column.test +33 -0
- data/test/command/suite/search/condition/query/syntax_error.catalog.json +36 -0
- data/test/command/suite/search/condition/query/syntax_error.expected +48 -0
- data/test/command/suite/search/condition/query/syntax_error.test +33 -0
- data/test/command/suite/search/condition/query.expected +24 -0
- data/test/command/suite/search/condition/query.test +23 -0
- data/test/command/suite/search/condition/script.expected +24 -0
- data/test/command/suite/search/condition/script.test +26 -0
- data/test/command/suite/search/error/cyclic-source.expected +14 -0
- data/test/command/suite/search/error/cyclic-source.test +12 -0
- data/test/command/suite/search/error/deeply-cyclic-source.expected +17 -0
- data/test/command/suite/search/error/deeply-cyclic-source.test +15 -0
- data/test/command/suite/search/error/missing-source-parameter.expected +13 -0
- data/test/command/suite/search/error/missing-source-parameter.test +11 -0
- data/test/command/suite/search/error/no-query.expected +9 -0
- data/test/command/suite/search/error/no-query.test +7 -0
- data/test/command/suite/search/error/unknown-source.expected +52 -0
- data/test/command/suite/search/error/unknown-source.test +12 -0
- data/test/command/suite/search/group/count.expected +10 -0
- data/test/command/suite/search/group/count.test +18 -0
- data/test/command/suite/search/group/limit.expected +15 -0
- data/test/command/suite/search/group/limit.test +20 -0
- data/test/command/suite/search/group/string.expected +32 -0
- data/test/command/suite/search/group/string.test +40 -0
- data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
- data/test/command/suite/search/group/subrecord/with-sort.expected +30 -0
- data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
- data/test/command/suite/search/multiple/chained.expected +41 -0
- data/test/command/suite/search/multiple/chained.test +39 -0
- data/test/command/suite/search/multiple/parallel.expected +35 -0
- data/test/command/suite/search/multiple/parallel.test +35 -0
- data/test/command/suite/search/output/attributes/invalid.catalog.json +13 -0
- data/test/command/suite/search/output/attributes/invalid.expected +44 -0
- data/test/command/suite/search/output/attributes/invalid.test +28 -0
- data/test/command/suite/search/range/only-output.expected +24 -0
- data/test/command/suite/search/range/only-output.test +23 -0
- data/test/command/suite/search/range/only-sort.expected +24 -0
- data/test/command/suite/search/range/only-sort.test +26 -0
- data/test/command/suite/search/range/sort-and-output.expected +21 -0
- data/test/command/suite/search/range/sort-and-output.test +27 -0
- data/test/command/suite/search/range/too-large-output-offset.expected +12 -0
- data/test/command/suite/search/range/too-large-output-offset.test +23 -0
- data/test/command/suite/search/range/too-large-sort-offset.expected +12 -0
- data/test/command/suite/search/range/too-large-sort-offset.test +26 -0
- data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
- data/test/command/suite/search/response/elapsed_time.expected +11 -0
- data/test/command/suite/search/response/elapsed_time.test +26 -0
- data/test/command/suite/search/response/records/value/time.expected +20 -0
- data/test/command/suite/search/response/records/value/time.test +22 -0
- data/test/command/suite/search/simple.expected +48 -0
- data/test/command/suite/search/simple.test +22 -0
- data/test/command/suite/search/sort/default-offset-limit.expected +39 -0
- data/test/command/suite/search/sort/default-offset-limit.test +24 -0
- data/test/command/suite/search/sort/invisible-column.expected +24 -0
- data/test/command/suite/search/sort/invisible-column.test +26 -0
- data/test/command/suite/watch/subscribe.expected +6 -0
- data/test/command/suite/watch/subscribe.test +9 -0
- data/test/command/suite/watch/unsubscribe.expected +6 -0
- data/test/command/suite/watch/unsubscribe.test +9 -0
- data/test/performance/run-test.rb +56 -0
- data/test/performance/watch/catalog.json +33 -0
- data/test/performance/watch/feed.json +9 -0
- data/test/performance/watch/fluentd.conf +11 -0
- data/test/performance/watch/subscribe.json +3 -0
- data/test/unit/catalog/test_collection_volume.rb +103 -0
- data/test/unit/catalog/test_dataset.rb +104 -0
- data/test/unit/catalog/test_schema.rb +226 -0
- data/test/unit/catalog/test_single_volume.rb +31 -0
- data/test/unit/catalog/test_slice.rb +92 -0
- data/test/unit/catalog/test_version1.rb +361 -0
- data/test/unit/catalog/test_version2.rb +124 -0
- data/test/unit/catalog/test_version2_validator.rb +66 -0
- data/test/unit/catalog/test_volume_collection.rb +50 -0
- data/test/unit/fixtures/array.grn +18 -0
- data/test/unit/fixtures/catalog/version1.json +40 -0
- data/test/unit/fixtures/catalog/version2.json +62 -0
- data/test/unit/fixtures/document.grn +34 -0
- data/test/unit/fixtures/reference/array.grn +11 -0
- data/test/unit/fixtures/reference/hash.grn +7 -0
- data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
- data/test/unit/helper/fixture.rb +28 -0
- data/test/unit/helper/plugin_helper.rb +38 -0
- data/test/unit/helper/sandbox.rb +86 -0
- data/test/unit/helper/stub_worker.rb +27 -0
- data/test/unit/helper/watch_helper.rb +23 -0
- data/test/unit/helper.rb +28 -0
- data/test/unit/plugins/crud/test_add.rb +190 -0
- data/test/unit/plugins/groonga/select/test_adapter_input.rb +510 -0
- data/test/unit/plugins/groonga/select/test_adapter_output.rb +201 -0
- data/test/unit/plugins/groonga/test_column_create.rb +171 -0
- data/test/unit/plugins/groonga/test_column_list.rb +170 -0
- data/test/unit/plugins/groonga/test_column_remove.rb +98 -0
- data/test/unit/plugins/groonga/test_column_rename.rb +105 -0
- data/test/unit/plugins/groonga/test_delete.rb +127 -0
- data/test/unit/plugins/groonga/test_table_create.rb +147 -0
- data/test/unit/plugins/groonga/test_table_list.rb +184 -0
- data/test/unit/plugins/groonga/test_table_remove.rb +61 -0
- data/test/unit/plugins/search/planner/test_basic.rb +120 -0
- data/test/unit/plugins/search/planner/test_group_by.rb +573 -0
- data/test/unit/plugins/search/planner/test_output.rb +388 -0
- data/test/unit/plugins/search/planner/test_sort_by.rb +938 -0
- data/test/unit/plugins/search/test_collector.rb +806 -0
- data/test/unit/plugins/search/test_handler.rb +930 -0
- data/test/unit/plugins/search/test_planner.rb +174 -0
- data/test/unit/plugins/test_basic.rb +510 -0
- data/test/unit/plugins/test_groonga.rb +70 -0
- data/test/unit/plugins/test_watch.rb +211 -0
- data/test/unit/run-test.rb +56 -0
- data/test/unit/test_catalog_generator.rb +93 -0
- data/test/unit/test_message_matcher.rb +160 -0
- data/test/unit/test_schema_applier.rb +59 -0
- data/test/unit/test_sweeper.rb +95 -0
- data/test/unit/test_watch_schema.rb +57 -0
- data/test/unit/test_watcher.rb +336 -0
- metadata +759 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2014 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
|
+
module Droonga
|
|
19
|
+
class Error < StandardError
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class MultiplexError < Error
|
|
23
|
+
attr_reader :errors
|
|
24
|
+
|
|
25
|
+
def initialize(errors=[])
|
|
26
|
+
@errors = errors
|
|
27
|
+
error_messages = @errors.collect do |error|
|
|
28
|
+
error.message
|
|
29
|
+
end
|
|
30
|
+
message = error_messages.sort.join("\n-----------------------\n")
|
|
31
|
+
super(message)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# the base class for any error which can be described as a Droonga message
|
|
36
|
+
class ErrorMessage < Error
|
|
37
|
+
STATUS_CODE = nil
|
|
38
|
+
|
|
39
|
+
attr_reader :detail
|
|
40
|
+
|
|
41
|
+
def initialize(message, detail=nil)
|
|
42
|
+
@detail = detail
|
|
43
|
+
super(message)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def name
|
|
47
|
+
self.class.name.split("::").last
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def status_code
|
|
51
|
+
self.class::STATUS_CODE
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def response_body
|
|
55
|
+
body = {
|
|
56
|
+
"name" => name,
|
|
57
|
+
"message" => message,
|
|
58
|
+
}
|
|
59
|
+
body["detail"] = @detail unless @detail.nil?
|
|
60
|
+
body
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# TODO: Move to common file for runners
|
|
65
|
+
class UnsupportedMessageError < Error
|
|
66
|
+
attr_reader :phase, :message
|
|
67
|
+
def initialize(phase, message)
|
|
68
|
+
@phase = phase
|
|
69
|
+
@message = message
|
|
70
|
+
super("[#{@phase}] Unsupported message: #{@message.inspect}")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
15
|
+
|
|
16
|
+
require "droonga/error"
|
|
17
|
+
require "droonga/status_code"
|
|
18
|
+
|
|
19
|
+
module Droonga
|
|
20
|
+
module ErrorMessages
|
|
21
|
+
class InternalServerError < ErrorMessage
|
|
22
|
+
STATUS_CODE = StatusCode::INTERNAL_SERVER_ERROR
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class BadRequest < ErrorMessage
|
|
26
|
+
STATUS_CODE = StatusCode::BAD_REQUEST
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class NotFound < ErrorMessage
|
|
30
|
+
STATUS_CODE = StatusCode::NOT_FOUND
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
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 "coolio"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class EventLoop
|
|
22
|
+
def initialize(loop)
|
|
23
|
+
@loop = loop
|
|
24
|
+
@loop_breaker = Coolio::AsyncWatcher.new
|
|
25
|
+
@loop_breaker.attach(@loop)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def attach(watcher)
|
|
29
|
+
@loop.attach(watcher)
|
|
30
|
+
break_current_loop
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def break_current_loop
|
|
34
|
+
@loop_breaker.signal
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def run
|
|
38
|
+
@loop.run
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def stop
|
|
42
|
+
@loop.stop
|
|
43
|
+
break_current_loop
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/droonga/farm.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
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/slice"
|
|
19
|
+
|
|
20
|
+
module Droonga
|
|
21
|
+
class Farm
|
|
22
|
+
def initialize(name, catalog, loop, options={})
|
|
23
|
+
@name = name
|
|
24
|
+
@catalog = catalog
|
|
25
|
+
@loop = loop
|
|
26
|
+
@options = options
|
|
27
|
+
@slices = {}
|
|
28
|
+
slices = @catalog.slices(name)
|
|
29
|
+
slices.each do |slice_name, slice_options|
|
|
30
|
+
dataset = @catalog.datasets[slice_options[:dataset]]
|
|
31
|
+
slice = Droonga::Slice.new(dataset,
|
|
32
|
+
@loop,
|
|
33
|
+
@options.merge(slice_options))
|
|
34
|
+
@slices[slice_name] = slice
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def start
|
|
39
|
+
@slices.each_value do |slice|
|
|
40
|
+
slice.start
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def shutdown
|
|
45
|
+
threads = []
|
|
46
|
+
@slices.each_value do |slice|
|
|
47
|
+
threads << Thread.new do
|
|
48
|
+
slice.shutdown
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
threads.each(&:join)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def process(slice_name, message)
|
|
55
|
+
@slices[slice_name].process(message)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Copyright (C) 2014 Droonga Project
|
|
2
|
+
#
|
|
3
|
+
# This library is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
5
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This library is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
10
|
+
# Lesser General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
13
|
+
# License along with this library; if not, write to the Free Software
|
|
14
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
15
|
+
|
|
16
|
+
require "socket"
|
|
17
|
+
|
|
18
|
+
require "msgpack"
|
|
19
|
+
|
|
20
|
+
require "droonga/loggable"
|
|
21
|
+
require "droonga/event_loop"
|
|
22
|
+
|
|
23
|
+
module Droonga
|
|
24
|
+
class FluentMessageReceiver
|
|
25
|
+
include Loggable
|
|
26
|
+
|
|
27
|
+
def initialize(loop, options={}, &on_message)
|
|
28
|
+
@loop = loop
|
|
29
|
+
@listen_fd = options[:listen_fd]
|
|
30
|
+
@heartbeat_fd = options[:heartbeat_fd]
|
|
31
|
+
@server = nil
|
|
32
|
+
@clients = []
|
|
33
|
+
@on_message = on_message
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def start
|
|
37
|
+
logger.trace("start: start")
|
|
38
|
+
start_heartbeat_receiver
|
|
39
|
+
start_server
|
|
40
|
+
logger.trace("start: done")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def shutdown
|
|
44
|
+
logger.trace("shutdown: start")
|
|
45
|
+
shutdown_server
|
|
46
|
+
shutdown_clients
|
|
47
|
+
shutdown_heartbeat_receiver
|
|
48
|
+
logger.trace("shutdown: done")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
def start_heartbeat_receiver
|
|
53
|
+
logger.trace("start_heartbeat_receiver: start")
|
|
54
|
+
@heartbeat_receiver = HeartbeatReceiver.new(@loop, @heartbeat_fd)
|
|
55
|
+
@heartbeat_receiver.start
|
|
56
|
+
logger.trace("start_heartbeat_receiver: done")
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def shutdown_heartbeat_receiver
|
|
60
|
+
logger.trace("shutdown_heartbeat_receiver: start")
|
|
61
|
+
@heartbeat_receiver.shutdown
|
|
62
|
+
logger.trace("shutdown_heartbeat_receiver: done")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def start_server
|
|
66
|
+
logger.trace("start_server: start")
|
|
67
|
+
|
|
68
|
+
@clients = []
|
|
69
|
+
@server = create_server do |connection|
|
|
70
|
+
client = Client.new(connection) do |tag, time, record|
|
|
71
|
+
@on_message.call(tag, time, record)
|
|
72
|
+
end
|
|
73
|
+
@clients << client
|
|
74
|
+
end
|
|
75
|
+
@loop.attach(@server)
|
|
76
|
+
|
|
77
|
+
logger.trace("start_server: done")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def create_server(&block)
|
|
81
|
+
Coolio::Server.new(TCPServer.for_fd(@listen_fd), Coolio::TCPSocket, &block)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def shutdown_server
|
|
85
|
+
@server.close
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def shutdown_clients
|
|
89
|
+
@clients.each do |client|
|
|
90
|
+
client.close
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def log_tag
|
|
95
|
+
"fluent-message-receiver"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
class HeartbeatReceiver
|
|
99
|
+
def initialize(loop, fd)
|
|
100
|
+
@loop = loop
|
|
101
|
+
@fd = fd
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def start
|
|
105
|
+
@socket = UDPSocket.for_fd(@fd)
|
|
106
|
+
|
|
107
|
+
@watcher = Coolio::IOWatcher.new(@socket, "r")
|
|
108
|
+
on_readable = lambda do
|
|
109
|
+
receive_heartbeat
|
|
110
|
+
end
|
|
111
|
+
@watcher.on_readable do
|
|
112
|
+
on_readable.call
|
|
113
|
+
end
|
|
114
|
+
@loop.attach(@watcher)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def shutdown
|
|
118
|
+
@socket.close
|
|
119
|
+
@watcher.detach
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
private
|
|
123
|
+
def receive_heartbeat
|
|
124
|
+
address = nil
|
|
125
|
+
begin
|
|
126
|
+
_, address = @socket.recvfrom(1024)
|
|
127
|
+
rescue SystamCallError
|
|
128
|
+
return
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
host = address[3]
|
|
132
|
+
port = address[1]
|
|
133
|
+
send_back_heartbeat(host, port)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def send_back_heartbeat(host, port)
|
|
137
|
+
data = "\0"
|
|
138
|
+
flags = 0
|
|
139
|
+
begin
|
|
140
|
+
@socket.send(data, flags, host, port)
|
|
141
|
+
rescue SystemCallError
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
class Client
|
|
147
|
+
include Loggable
|
|
148
|
+
|
|
149
|
+
def initialize(io, &on_message)
|
|
150
|
+
@io = io
|
|
151
|
+
@on_message = on_message
|
|
152
|
+
@unpacker = MessagePack::Unpacker.new
|
|
153
|
+
on_read = lambda do |data|
|
|
154
|
+
feed(data)
|
|
155
|
+
end
|
|
156
|
+
@io.on_read do |data|
|
|
157
|
+
on_read.call(data)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def close
|
|
162
|
+
@io.close
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
def feed(data)
|
|
167
|
+
@unpacker.feed_each(data) do |object|
|
|
168
|
+
tag = object[0]
|
|
169
|
+
case object[1]
|
|
170
|
+
when String # PackedForward message
|
|
171
|
+
entries = MessagePack.unpack(object[1])
|
|
172
|
+
when Array # Forward message
|
|
173
|
+
entries = object[1]
|
|
174
|
+
when Integer, Float # Message message
|
|
175
|
+
entries = [[object[1], object[2]]]
|
|
176
|
+
else
|
|
177
|
+
logger.error("unknown message", :message => object)
|
|
178
|
+
next
|
|
179
|
+
end
|
|
180
|
+
entries.each do |time, record|
|
|
181
|
+
@on_message.call(tag, time || Time.now.to_i, record)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def log_tag
|
|
187
|
+
"fluent-message-receiver::client"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
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 "thread"
|
|
19
|
+
|
|
20
|
+
require "cool.io"
|
|
21
|
+
|
|
22
|
+
require "droonga/message-pack-packer"
|
|
23
|
+
|
|
24
|
+
require "droonga/loggable"
|
|
25
|
+
|
|
26
|
+
module Droonga
|
|
27
|
+
class FluentMessageSender
|
|
28
|
+
include Loggable
|
|
29
|
+
|
|
30
|
+
def initialize(loop, host, port)
|
|
31
|
+
@loop = loop
|
|
32
|
+
@host = host
|
|
33
|
+
@port = port
|
|
34
|
+
@socket = nil
|
|
35
|
+
@buffer = []
|
|
36
|
+
@write_mutex = Mutex.new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def start
|
|
40
|
+
logger.trace("start: start")
|
|
41
|
+
start_writer
|
|
42
|
+
logger.trace("start: done")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def shutdown
|
|
46
|
+
logger.trace("shutdown: start")
|
|
47
|
+
shutdown_writer
|
|
48
|
+
shutdown_socket
|
|
49
|
+
logger.trace("shutdown: done")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def send(tag, data)
|
|
53
|
+
logger.trace("send: start")
|
|
54
|
+
fluent_message = [tag, Time.now.to_i, data]
|
|
55
|
+
packed_fluent_message = MessagePackPacker.pack(fluent_message)
|
|
56
|
+
@write_mutex.synchronize do
|
|
57
|
+
@buffer << packed_fluent_message
|
|
58
|
+
unless @signaling
|
|
59
|
+
@signaling = true
|
|
60
|
+
@writer.signal
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
logger.trace("send: done")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
def connected?
|
|
68
|
+
not @socket.nil?
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def connect
|
|
72
|
+
logger.trace("connect: start")
|
|
73
|
+
|
|
74
|
+
log_write_complete = lambda do
|
|
75
|
+
logger.trace("write completed")
|
|
76
|
+
end
|
|
77
|
+
log_connect = lambda do
|
|
78
|
+
logger.trace("connected to #{@host}:#{@port}")
|
|
79
|
+
end
|
|
80
|
+
log_failed = lambda do
|
|
81
|
+
logger.error("failed to connect to #{@host}:#{@port}")
|
|
82
|
+
@socket = nil
|
|
83
|
+
end
|
|
84
|
+
on_close = lambda do
|
|
85
|
+
@socket = nil
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
@socket = Coolio::TCPSocket.connect(@host, @port)
|
|
89
|
+
@socket.on_write_complete do
|
|
90
|
+
log_write_complete.call
|
|
91
|
+
end
|
|
92
|
+
@socket.on_connect do
|
|
93
|
+
log_connect.call
|
|
94
|
+
end
|
|
95
|
+
@socket.on_connect_failed do
|
|
96
|
+
log_failed.call
|
|
97
|
+
end
|
|
98
|
+
@socket.on_close do
|
|
99
|
+
on_close.call
|
|
100
|
+
end
|
|
101
|
+
@loop.attach(@socket)
|
|
102
|
+
|
|
103
|
+
logger.trace("connect: done")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def shutdown_socket
|
|
107
|
+
return unless connected?
|
|
108
|
+
@socket.close unless @socket.closed?
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def start_writer
|
|
112
|
+
@writer = Coolio::AsyncWatcher.new
|
|
113
|
+
@signaling = false
|
|
114
|
+
|
|
115
|
+
on_signal = lambda do
|
|
116
|
+
@write_mutex.synchronize do
|
|
117
|
+
@signaling = false
|
|
118
|
+
connect unless connected?
|
|
119
|
+
@buffer.each do |data|
|
|
120
|
+
@socket.write(data)
|
|
121
|
+
end
|
|
122
|
+
@buffer.clear
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
@writer.on_signal do
|
|
126
|
+
on_signal.call
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
@loop.attach(@writer)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def shutdown_writer
|
|
133
|
+
@writer.detach
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def log_tag
|
|
137
|
+
"[#{Process.ppid}][#{Process.pid}] fluent-message-sender"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
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/loggable"
|
|
19
|
+
require "droonga/event_loop"
|
|
20
|
+
require "droonga/fluent_message_sender"
|
|
21
|
+
|
|
22
|
+
module Droonga
|
|
23
|
+
class Forwarder
|
|
24
|
+
include Loggable
|
|
25
|
+
|
|
26
|
+
def initialize(loop)
|
|
27
|
+
@loop = loop
|
|
28
|
+
@senders = {}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def start
|
|
32
|
+
logger.trace("start: start")
|
|
33
|
+
logger.trace("start: done")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def shutdown
|
|
37
|
+
logger.trace("shutdown: start")
|
|
38
|
+
@senders.each_value do |sender|
|
|
39
|
+
sender.shutdown
|
|
40
|
+
end
|
|
41
|
+
logger.trace("shutdown: done")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def forward(message, destination)
|
|
45
|
+
logger.trace("forward: start")
|
|
46
|
+
command = destination["type"]
|
|
47
|
+
receiver = destination["to"]
|
|
48
|
+
arguments = destination["arguments"]
|
|
49
|
+
output(receiver, message, command, arguments)
|
|
50
|
+
logger.trace("forward: done")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
def output(receiver, message, command, arguments)
|
|
55
|
+
logger.trace("output: start")
|
|
56
|
+
# TODO: IMPROVE ME: Should not use "unless" and "and". It is confused.
|
|
57
|
+
unless receiver.is_a?(String) and command.is_a?(String)
|
|
58
|
+
logger.trace("output: abort: invalid argument",
|
|
59
|
+
:receiver => receiver,
|
|
60
|
+
:command => command)
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
unless receiver =~ /\A(.*):(\d+)\/(.*?)(\?.+)?\z/
|
|
64
|
+
raise "format: hostname:port/tag(?params)"
|
|
65
|
+
end
|
|
66
|
+
host = $1
|
|
67
|
+
port = $2
|
|
68
|
+
tag = $3
|
|
69
|
+
params = $4
|
|
70
|
+
sender = find_sender(host, port, params)
|
|
71
|
+
unless sender
|
|
72
|
+
logger.trace("output: abort: no sender",
|
|
73
|
+
:host => host,
|
|
74
|
+
:port => port,
|
|
75
|
+
:params => params)
|
|
76
|
+
return
|
|
77
|
+
end
|
|
78
|
+
override_message = {
|
|
79
|
+
"type" => command,
|
|
80
|
+
}
|
|
81
|
+
override_message["arguments"] = arguments if arguments
|
|
82
|
+
message = message.merge(override_message)
|
|
83
|
+
output_tag = "#{tag}.message"
|
|
84
|
+
log_info = "<#{receiver}>:<#{output_tag}>"
|
|
85
|
+
logger.trace("output: post: start: #{log_info}")
|
|
86
|
+
sender.send(output_tag, message)
|
|
87
|
+
logger.trace("output: post: done: #{log_info}")
|
|
88
|
+
logger.trace("output: done")
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def find_sender(host, port, params)
|
|
92
|
+
connection_id = extract_connection_id(params)
|
|
93
|
+
destination = "#{host}:#{port}"
|
|
94
|
+
destination << "?#{connection_id}" if connection_id
|
|
95
|
+
|
|
96
|
+
@senders[destination] ||= create_sender(host, port)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def extract_connection_id(params)
|
|
100
|
+
return nil unless params
|
|
101
|
+
|
|
102
|
+
if /[\?&;]connection_id=([^&;]+)/ =~ params
|
|
103
|
+
$1
|
|
104
|
+
else
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def create_sender(host, port)
|
|
110
|
+
sender = FluentMessageSender.new(@loop, host, port)
|
|
111
|
+
sender.start
|
|
112
|
+
sender
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def log_tag
|
|
116
|
+
"[#{Process.ppid}][#{Process.pid}] forwarder"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright (C) 2014 Droonga Project
|
|
2
|
+
#
|
|
3
|
+
# This library is free software; you can redistribute it and/or
|
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
5
|
+
# License version 2.1 as published by the Free Software Foundation.
|
|
6
|
+
#
|
|
7
|
+
# This library is distributed in the hope that it will be useful,
|
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
10
|
+
# Lesser General Public License for more details.
|
|
11
|
+
#
|
|
12
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
13
|
+
# License along with this library; if not, write to the Free Software
|
|
14
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
15
|
+
|
|
16
|
+
require "droonga/pluggable"
|
|
17
|
+
require "droonga/loggable"
|
|
18
|
+
require "droonga/plugin/metadata/input_message"
|
|
19
|
+
require "droonga/plugin/metadata/handler_action"
|
|
20
|
+
require "droonga/error_messages"
|
|
21
|
+
|
|
22
|
+
module Droonga
|
|
23
|
+
class Handler
|
|
24
|
+
extend Pluggable
|
|
25
|
+
include Loggable
|
|
26
|
+
include ErrorMessages
|
|
27
|
+
|
|
28
|
+
class << self
|
|
29
|
+
def message
|
|
30
|
+
Plugin::Metadata::InputMessage.new(self)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def action
|
|
34
|
+
Plugin::Metadata::HandlerAction.new(self)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
attr_reader :messenger, :loop
|
|
39
|
+
def initialize(name, context, messenger, loop)
|
|
40
|
+
@name = name
|
|
41
|
+
@context = context
|
|
42
|
+
@messenger = messenger
|
|
43
|
+
@loop = loop
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def handle(message)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|