fluent-plugin-droonga 0.9.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.dir-locals.el +3 -0
  3. data/.travis.yml +6 -2
  4. data/README.md +6 -7
  5. data/Rakefile +23 -6
  6. data/fluent-plugin-droonga.gemspec +2 -2
  7. data/lib/droonga/adapter.rb +12 -3
  8. data/lib/droonga/adapter_runner.rb +28 -23
  9. data/lib/droonga/catalog/base.rb +7 -111
  10. data/lib/droonga/catalog/dataset.rb +13 -25
  11. data/lib/droonga/catalog/errors.rb +94 -0
  12. data/lib/droonga/catalog/schema.rb +277 -0
  13. data/lib/droonga/catalog/version1.rb +404 -0
  14. data/lib/droonga/catalog/version2.rb +160 -0
  15. data/lib/droonga/catalog_loader.rb +27 -4
  16. data/lib/droonga/catalog_observer.rb +44 -6
  17. data/lib/droonga/collector.rb +12 -10
  18. data/lib/droonga/{handler_plugin.rb → collector_message.rb} +47 -20
  19. data/lib/droonga/collector_runner.rb +64 -0
  20. data/lib/droonga/collectors.rb +18 -0
  21. data/lib/droonga/{catalog.rb → collectors/add.rb} +9 -7
  22. data/lib/droonga/{command_repository.rb → collectors/and.rb} +7 -14
  23. data/lib/droonga/collectors/sum.rb +26 -0
  24. data/lib/droonga/dispatcher.rb +74 -41
  25. data/lib/droonga/distributed_command_planner.rb +2 -2
  26. data/lib/droonga/engine.rb +13 -5
  27. data/lib/droonga/{message_processing_error.rb → error.rb} +33 -12
  28. data/lib/droonga/{plugin/planner/search.rb → error_messages.rb} +12 -10
  29. data/lib/droonga/farm.rb +15 -14
  30. data/lib/droonga/fluent_message_sender.rb +15 -11
  31. data/lib/droonga/forwarder.rb +22 -18
  32. data/lib/droonga/handler.rb +8 -2
  33. data/lib/droonga/handler_runner.rb +47 -26
  34. data/lib/droonga/input_message.rb +6 -6
  35. data/lib/droonga/{command.rb → loggable.rb} +7 -14
  36. data/lib/droonga/logger.rb +56 -15
  37. data/lib/droonga/message_matcher.rb +12 -7
  38. data/lib/droonga/message_pusher.rb +8 -4
  39. data/lib/droonga/message_receiver.rb +11 -9
  40. data/lib/droonga/output_message.rb +2 -0
  41. data/lib/droonga/planner.rb +21 -10
  42. data/lib/droonga/plugin.rb +15 -0
  43. data/lib/droonga/plugin/metadata/{adapter_message.rb → adapter_input_message.rb} +6 -14
  44. data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
  45. data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
  46. data/lib/droonga/plugin/metadata/input_message.rb +15 -0
  47. data/lib/droonga/plugin_loader.rb +33 -25
  48. data/lib/droonga/plugin_registry.rb +9 -1
  49. data/lib/droonga/plugins/basic.rb +54 -0
  50. data/lib/droonga/plugins/crud.rb +36 -15
  51. data/lib/droonga/plugins/error.rb +5 -4
  52. data/lib/droonga/plugins/groonga.rb +9 -6
  53. data/lib/droonga/plugins/groonga/column_create.rb +10 -5
  54. data/lib/droonga/plugins/groonga/generic_command.rb +2 -8
  55. data/lib/droonga/plugins/groonga/generic_response.rb +2 -2
  56. data/lib/droonga/plugins/groonga/select.rb +2 -2
  57. data/lib/droonga/plugins/groonga/table_create.rb +9 -4
  58. data/lib/droonga/plugins/groonga/table_remove.rb +10 -5
  59. data/lib/droonga/plugins/search.rb +106 -5
  60. data/lib/droonga/plugins/search/distributed_search_planner.rb +398 -0
  61. data/lib/droonga/plugins/watch.rb +41 -20
  62. data/lib/droonga/processor.rb +12 -9
  63. data/lib/droonga/{plugin/collector/basic.rb → reducer.rb} +36 -50
  64. data/lib/droonga/replier.rb +7 -4
  65. data/lib/droonga/searcher.rb +40 -37
  66. data/lib/droonga/server.rb +8 -6
  67. data/lib/droonga/session.rb +17 -7
  68. data/lib/droonga/single_step.rb +53 -0
  69. data/lib/droonga/{plugin/planner/watch.rb → single_step_definition.rb} +27 -26
  70. data/lib/droonga/{partition.rb → slice.rb} +23 -12
  71. data/lib/droonga/status_code.rb +25 -0
  72. data/lib/droonga/step_runner.rb +63 -0
  73. data/lib/droonga/watch_schema.rb +7 -3
  74. data/lib/droonga/watcher.rb +4 -4
  75. data/lib/droonga/worker.rb +6 -6
  76. data/lib/fluent/plugin/out_droonga.rb +27 -2
  77. data/sample/cluster/catalog.json +33 -32
  78. data/test/command/config/default/catalog.json +72 -45
  79. data/test/command/config/version1/catalog.json +68 -0
  80. data/test/command/config/version1/fluentd.conf +11 -0
  81. data/test/command/suite/message/error/missing-dataset.expected +1 -1
  82. data/test/command/suite/message/error/unknown-dataset.expected +1 -1
  83. data/test/command/suite/message/error/unknown-type.expected +13 -0
  84. data/test/command/suite/message/error/{unknown-command.test → unknown-type.test} +1 -1
  85. data/test/command/suite/search/error/missing-source-parameter.expected +1 -1
  86. data/test/command/suite/search/error/unknown-source.expected +15 -3
  87. data/test/command/suite/watch/subscribe.expected +1 -3
  88. data/test/command/suite/watch/unsubscribe.expected +1 -3
  89. data/test/performance/watch/catalog.json +1 -0
  90. data/test/unit/catalog/test_dataset.rb +16 -358
  91. data/test/unit/catalog/test_schema.rb +285 -0
  92. data/test/unit/catalog/test_version1.rb +222 -28
  93. data/test/unit/catalog/test_version2.rb +155 -0
  94. data/test/unit/fixtures/catalog/version2.json +62 -0
  95. data/test/unit/helper/distributed_search_planner_helper.rb +2 -2
  96. data/test/unit/plugins/crud/test_add.rb +13 -13
  97. data/test/unit/plugins/groonga/test_column_create.rb +14 -11
  98. data/test/unit/plugins/groonga/test_table_create.rb +4 -9
  99. data/test/unit/plugins/groonga/test_table_remove.rb +4 -9
  100. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_basic.rb +0 -0
  101. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_group_by.rb +0 -0
  102. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_output.rb +0 -0
  103. data/test/unit/{plugin/planner/search_planner → plugins/search/planner}/test_sort_by.rb +0 -0
  104. data/test/unit/{plugin/collector/test_search.rb → plugins/search/test_collector.rb} +40 -39
  105. data/test/unit/plugins/{test_search.rb → search/test_handler.rb} +6 -5
  106. data/test/unit/{plugin/planner/test_search.rb → plugins/search/test_planner.rb} +3 -3
  107. data/test/unit/{plugin/collector → plugins}/test_basic.rb +68 -50
  108. data/test/unit/plugins/test_groonga.rb +2 -15
  109. data/test/unit/plugins/test_watch.rb +25 -22
  110. data/test/unit/test_message_matcher.rb +29 -6
  111. data/test/unit/test_output.rb +4 -0
  112. metadata +58 -50
  113. data/lib/droonga/collector_plugin.rb +0 -50
  114. data/lib/droonga/legacy_pluggable.rb +0 -66
  115. data/lib/droonga/legacy_plugin.rb +0 -57
  116. data/lib/droonga/legacy_plugin_repository.rb +0 -54
  117. data/lib/droonga/planner_plugin.rb +0 -54
  118. data/lib/droonga/plugin/collector/search.rb +0 -98
  119. data/lib/droonga/plugin/planner/crud.rb +0 -49
  120. data/lib/droonga/plugin/planner/distributed_search_planner.rb +0 -393
  121. data/lib/droonga/plugin/planner/groonga.rb +0 -54
  122. data/lib/droonga/plugin_registerable.rb +0 -75
  123. data/test/command/suite/message/error/unknown-command.expected +0 -13
  124. data/test/unit/test_command_repository.rb +0 -39
  125. data/test/unit/test_legacy_plugin.rb +0 -50
  126. data/test/unit/test_legacy_plugin_repository.rb +0 -89
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2013 Droonga Project
3
+ # Copyright (C) 2013-2014 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
@@ -16,20 +16,61 @@
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
18
  module Droonga
19
- module Logger
20
- module_function
21
- def info(message)
22
- if $log
23
- $log.info(message)
24
- end
25
- end
26
-
27
- def error(message, exception, additional_information={})
28
- if $log
29
- $log.error("#{message}: #{exception.message}(#{exception.class})",
30
- additional_information)
31
- $log.error_backtrace(exception.backtrace)
32
- end
19
+ class << self
20
+ def logger
21
+ @logger ||= Logger.new
22
+ end
23
+
24
+ def logger=(logger)
25
+ @logger = logger
26
+ end
27
+ end
28
+
29
+ class Logger
30
+ def initialize(options={})
31
+ @output = Fluent::PluginLogger.new($log)
32
+ depth_offset = options[:depth_offset] || 0
33
+ @output.instance_variable_set(:@depth_offset, 4 + depth_offset)
34
+ @tag = options[:tag]
35
+ end
36
+
37
+ def level
38
+ @output.level
39
+ end
40
+
41
+ def trace(message, data={})
42
+ log(:trace, message, data)
43
+ end
44
+
45
+ def debug(message, data={})
46
+ log(:debug, message, data)
47
+ end
48
+
49
+ def info(message, data={})
50
+ log(:info, message, data)
51
+ end
52
+
53
+ def warn(message, data={})
54
+ log(:warn, message, data)
55
+ end
56
+
57
+ def error(message, data={})
58
+ log(:error, message, data)
59
+ end
60
+
61
+ def exception(message, exception, data={})
62
+ log(:error,
63
+ "#{message}: #{exception.message}(#{exception.class})",
64
+ data)
65
+ @output.error_backtrace(exception.backtrace)
66
+ end
67
+
68
+ private
69
+ def log(level, message, data)
70
+ message = "#{@tag}: #{message}" if @tag
71
+ arguments = [message]
72
+ arguments << data unless data.empty?
73
+ @output.send(level, *arguments)
33
74
  end
34
75
  end
35
76
  end
@@ -18,13 +18,13 @@ module Droonga
18
18
  #
19
19
  # It provides the small language. Here is the pattern syntax.
20
20
  #
21
- # * PATTERN = [TARGET_PATH, OPERATOR, ARGUMENTS*]
21
+ # * PATTERN = [TARGET_PATH, OPERATOR, ARGUMENT*]
22
22
  # * PATTERN = [PATTERN, LOGICAL_OPERATOR, PATTERN]
23
23
  # * TARGET_PATH = "COMPONENT(.COMPONENT)*"
24
- # * OPERATOR = :equal, :in, :include?, :exist?
24
+ # * OPERATOR = :equal, :in, :include, :exist, :start_with
25
25
  # (More operators may be added in the future.
26
- # For example, :start_with and so on.)
27
- # * ARGUMENTS = OBJECT_DEFINED_IN_JSON*
26
+ # For example, :end_with and so on.)
27
+ # * ARGUMENT = OBJECT_DEFINED_IN_JSON
28
28
  # * LOGICAL_OPERATOR = :or (:add will be added.)
29
29
  #
30
30
  # For example:
@@ -86,15 +86,20 @@ module Droonga
86
86
  arguments.any? do |argument|
87
87
  argument.include?(target)
88
88
  end
89
- when :include?
89
+ when :include
90
90
  return false unless target.respond_to?(:include?)
91
91
  arguments.any? do |argument|
92
92
  target.include?(argument)
93
93
  end
94
- when :exist?
94
+ when :exist
95
95
  target != NONEXISTENT_PATH
96
+ when :start_with
97
+ return false unless target.respond_to?(:start_with?)
98
+ arguments.any? do |argument|
99
+ target.start_with?(argument)
100
+ end
96
101
  else
97
- raise ArgumentError, "Unknown operator"
102
+ raise ArgumentError, "Unknown operator: <#{operator}>"
98
103
  end
99
104
  end
100
105
  end
@@ -17,8 +17,12 @@
17
17
 
18
18
  require "msgpack"
19
19
 
20
+ require "droonga/logger"
21
+
20
22
  module Droonga
21
23
  class MessagePusher
24
+ include Loggable
25
+
22
26
  attr_reader :raw_receiver
23
27
  def initialize(loop)
24
28
  @loop = loop
@@ -32,15 +36,15 @@ module Droonga
32
36
  end
33
37
 
34
38
  def shutdown
35
- $log.trace("#{log_tag}: shutdown: start")
39
+ logger.trace("shutdown: start")
36
40
  socket_path = @raw_receiver.path
37
41
  @raw_receiver.close
38
42
  FileUtils.rm_f(socket_path)
39
- $log.trace("#{log_tag}: shutdown: done")
43
+ logger.trace("shutdown: done")
40
44
  end
41
45
 
42
46
  def push(message)
43
- $log.trace("#{log_tag}: push: start")
47
+ logger.trace("push: start")
44
48
  packed_message = message.to_msgpack
45
49
  path = @raw_receiver.path
46
50
  sender = Coolio::UNIXSocket.connect(path)
@@ -49,7 +53,7 @@ module Droonga
49
53
  close
50
54
  end
51
55
  @loop.attach(sender)
52
- $log.trace("#{log_tag}: push: done")
56
+ logger.trace("push: done")
53
57
  end
54
58
 
55
59
  private
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2013 Droonga Project
1
+ # Copyright (C) 2013-2014 Droonga Project
4
2
  #
5
3
  # This library is free software; you can redistribute it and/or
6
4
  # modify it under the terms of the GNU Lesser General Public
@@ -17,8 +15,12 @@
17
15
 
18
16
  require "msgpack"
19
17
 
18
+ require "droonga/loggable"
19
+
20
20
  module Droonga
21
21
  class MessageReceiver
22
+ include Loggable
23
+
22
24
  def initialize(loop, receiver, &callback)
23
25
  @loop = loop
24
26
  @receiver = Coolio::Server.new(receiver, Coolio::Socket) do |connection|
@@ -28,26 +30,26 @@ module Droonga
28
30
  end
29
31
 
30
32
  def start
31
- $log.trace("#{log_tag}: start: start")
33
+ logger.trace("start: start")
32
34
  @loop.attach(@receiver)
33
- $log.trace("#{log_tag}: start: done")
35
+ logger.trace("start: done")
34
36
  end
35
37
 
36
38
  def shutdown
37
- $log.trace("#{log_tag}: shutdown: start")
39
+ logger.trace("shutdown: start")
38
40
  @receiver.close
39
- $log.trace("#{log_tag}: shutdown: done")
41
+ logger.trace("shutdown: done")
40
42
  end
41
43
 
42
44
  private
43
45
  def setup_receive_handler(connection)
44
46
  unpacker = MessagePack::Unpacker.new
45
47
  on_read = lambda do |data|
46
- $log.trace("#{log_tag}: on_read: start")
48
+ logger.trace("on_read: start")
47
49
  unpacker.feed_each(data) do |message|
48
50
  @callback.call(message)
49
51
  end
50
- $log.trace("#{log_tag}: on_read: done")
52
+ logger.trace("on_read: done")
51
53
  end
52
54
  connection.on_read do |data|
53
55
  on_read.call(data)
@@ -13,6 +13,8 @@
13
13
  # License along with this library; if not, write to the Free Software
14
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
15
 
16
+ require "droonga/status_code"
17
+
16
18
  module Droonga
17
19
  class OutputMessage
18
20
  def initialize(raw_message)
@@ -13,25 +13,36 @@
13
13
  # License along with this library; if not, write to the Free Software
14
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
15
 
16
- require "droonga/legacy_pluggable"
17
- require "droonga/planner_plugin"
16
+ require "droonga/loggable"
17
+ require "droonga/distributed_command_planner"
18
+ require "droonga/error_messages"
18
19
 
19
20
  module Droonga
20
21
  class Planner
21
- include LegacyPluggable
22
+ include Loggable
23
+ include ErrorMessages
22
24
 
23
- def initialize(dispatcher, plugins)
24
- @dispatcher = dispatcher
25
- load_plugins(plugins)
25
+ def initialize
26
+ end
27
+
28
+ def plan(message)
29
+ raise NotImplemented, "#{self.class.name}\##{__method__} must implement."
26
30
  end
27
31
 
28
32
  private
29
- def instantiate_plugin(name)
30
- PlannerPlugin.repository.instantiate(name, self)
33
+ def scatter(message, options={})
34
+ planner = DistributedCommandPlanner.new(message)
35
+ planner.scatter
36
+ planner.key = options[:key]
37
+ planner.reduce(options[:reduce])
38
+ planner.plan
31
39
  end
32
40
 
33
- def log_tag
34
- "[#{Process.pid}] planner"
41
+ def broadcast(message, options={})
42
+ planner = DistributedCommandPlanner.new(message)
43
+ planner.broadcast(:write => options[:write])
44
+ planner.reduce(options[:reduce])
45
+ planner.plan
35
46
  end
36
47
  end
37
48
  end
@@ -14,8 +14,11 @@
14
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
15
 
16
16
  require "droonga/plugin_registry"
17
+ require "droonga/single_step_definition"
17
18
  require "droonga/adapter"
19
+ require "droonga/planner"
18
20
  require "droonga/handler"
21
+ require "droonga/collectors"
19
22
 
20
23
  module Droonga
21
24
  module Plugin
@@ -24,5 +27,17 @@ module Droonga
24
27
  @@registry ||= PluginRegistry.new
25
28
  end
26
29
  end
30
+
31
+ def register(name)
32
+ Plugin.registry.register(name, self)
33
+ end
34
+
35
+ def define_single_step(&block)
36
+ single_step_definitions << SingleStepDefinition.new(self, &block)
37
+ end
38
+
39
+ def single_step_definitions
40
+ @single_step_definitions ||= []
41
+ end
27
42
  end
28
43
  end
@@ -16,30 +16,22 @@
16
16
  module Droonga
17
17
  module Plugin
18
18
  module Metadata
19
- class AdapterMessage
19
+ class AdapterInputMessage
20
20
  def initialize(adapter_class)
21
21
  @adapter_class = adapter_class
22
22
  end
23
23
 
24
- def input_pattern
25
- configuration[:input_pattern]
24
+ def pattern
25
+ configuration[:pattern]
26
26
  end
27
27
 
28
- def input_pattern=(pattern)
29
- configuration[:input_pattern] = pattern
30
- end
31
-
32
- def output_pattern
33
- configuration[:output_pattern]
34
- end
35
-
36
- def output_pattern=(pattern)
37
- configuration[:output_pattern] = pattern
28
+ def pattern=(pattern)
29
+ configuration[:pattern] = pattern
38
30
  end
39
31
 
40
32
  private
41
33
  def configuration
42
- @adapter_class.options[:message] ||= {}
34
+ @adapter_class.options[:input_message] ||= {}
43
35
  end
44
36
  end
45
37
  end
@@ -0,0 +1,39 @@
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
+ module Droonga
17
+ module Plugin
18
+ module Metadata
19
+ class AdapterOutputMessage
20
+ def initialize(adapter_class)
21
+ @adapter_class = adapter_class
22
+ end
23
+
24
+ def pattern
25
+ configuration[:pattern]
26
+ end
27
+
28
+ def pattern=(pattern)
29
+ configuration[:pattern] = pattern
30
+ end
31
+
32
+ private
33
+ def configuration
34
+ @adapter_class.options[:output_message] ||= {}
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
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
+ module Droonga
17
+ module Plugin
18
+ module Metadata
19
+ class CollectorMessage
20
+ def initialize(plugin_class)
21
+ @plugin_class = plugin_class
22
+ end
23
+
24
+ def pattern
25
+ configuration[:pattern]
26
+ end
27
+
28
+ def pattern=(pattern)
29
+ configuration[:pattern] = pattern
30
+ end
31
+
32
+ private
33
+ def configuration
34
+ @plugin_class.options[:message] ||= {}
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -17,6 +17,19 @@ module Droonga
17
17
  module Plugin
18
18
  module Metadata
19
19
  class InputMessage
20
+ class NotStringMessageType < Error
21
+ def initialize(type)
22
+ super("You must specify a string as a message type. " +
23
+ "#{type.inspect} is not a string.")
24
+ end
25
+ end
26
+
27
+ class BlankMessageType < Error
28
+ def initialize
29
+ super("You must specify a non-empty string as a message type.")
30
+ end
31
+ end
32
+
20
33
  def initialize(plugin_class)
21
34
  @plugin_class = plugin_class
22
35
  end
@@ -26,6 +39,8 @@ module Droonga
26
39
  end
27
40
 
28
41
  def type=(type)
42
+ raise NotStringMessageType.new(type) unless type.is_a?(String)
43
+ raise BlankMessageType.new if type.empty?
29
44
  configuration[:type] = type
30
45
  end
31
46