fluent-plugin-droonga 0.0.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -0
  3. data/.yardopts +7 -0
  4. data/Gemfile +14 -2
  5. data/LICENSE.txt +1 -1
  6. data/README.md +1 -1
  7. data/Rakefile +27 -5
  8. data/benchmark/benchmark.rb +1 -1
  9. data/benchmark/utils.rb +9 -6
  10. data/benchmark/watch/benchmark-notify.rb +2 -2
  11. data/benchmark/watch/benchmark-publish.rb +1 -1
  12. data/benchmark/watch/benchmark-scan.rb +1 -1
  13. data/benchmark/watch/catalog.json +1 -1
  14. data/bin/grn2jsons +1 -1
  15. data/fluent-plugin-droonga.gemspec +5 -3
  16. data/lib/droonga/adapter.rb +13 -130
  17. data/lib/droonga/adapter_plugin.rb +51 -0
  18. data/lib/droonga/catalog.rb +2 -2
  19. data/lib/droonga/collector.rb +107 -0
  20. data/lib/droonga/collector_plugin.rb +82 -0
  21. data/lib/droonga/command_mapper.rb +1 -1
  22. data/lib/droonga/{proxy.rb → dispatcher.rb} +116 -151
  23. data/lib/droonga/distributor.rb +51 -0
  24. data/lib/droonga/distributor_plugin.rb +59 -0
  25. data/lib/droonga/engine.rb +9 -50
  26. data/lib/droonga/farm.rb +47 -0
  27. data/lib/droonga/forwarder.rb +125 -0
  28. data/lib/droonga/handler.rb +69 -60
  29. data/lib/droonga/handler_plugin.rb +22 -11
  30. data/lib/droonga/input_message.rb +51 -0
  31. data/lib/droonga/job_queue.rb +5 -1
  32. data/lib/droonga/job_queue_schema.rb +1 -1
  33. data/lib/droonga/logger.rb +1 -1
  34. data/lib/droonga/partition.rb +76 -0
  35. data/lib/droonga/pluggable.rb +62 -0
  36. data/lib/droonga/plugin.rb +18 -16
  37. data/lib/droonga/plugin/{adapter_groonga.rb → adapter/groonga.rb} +10 -10
  38. data/lib/droonga/plugin/adapter/groonga/select.rb +13 -4
  39. data/lib/droonga/plugin/collector/basic.rb +142 -0
  40. data/lib/droonga/plugin/distributor/crud.rb +43 -0
  41. data/lib/droonga/plugin/distributor/groonga.rb +37 -0
  42. data/lib/droonga/plugin/distributor/search.rb +273 -0
  43. data/lib/droonga/plugin/distributor/watch.rb +39 -0
  44. data/lib/droonga/plugin/{handler_add.rb → handler/add.rb} +6 -6
  45. data/lib/droonga/plugin/{handler_forward.rb → handler/forward.rb} +9 -4
  46. data/lib/droonga/plugin/{handler_groonga.rb → handler/groonga.rb} +36 -4
  47. data/lib/droonga/plugin/handler/groonga/column_create.rb +5 -9
  48. data/lib/droonga/plugin/handler/groonga/table_create.rb +9 -18
  49. data/lib/droonga/plugin/{handler_search.rb → handler/search.rb} +4 -4
  50. data/lib/droonga/plugin/{handler_watch.rb → handler/watch.rb} +4 -4
  51. data/lib/droonga/plugin_loader.rb +45 -0
  52. data/lib/droonga/plugin_registerable.rb +51 -0
  53. data/lib/droonga/plugin_repository.rb +56 -0
  54. data/lib/droonga/processor.rb +64 -0
  55. data/lib/droonga/searcher.rb +16 -7
  56. data/lib/droonga/server.rb +5 -9
  57. data/lib/droonga/sweeper.rb +1 -1
  58. data/lib/droonga/watch_schema.rb +1 -1
  59. data/lib/droonga/watcher.rb +1 -1
  60. data/lib/droonga/worker.rb +21 -9
  61. data/lib/fluent/plugin/out_droonga.rb +33 -15
  62. data/lib/groonga_command_converter.rb +1 -1
  63. data/sample/cluster/fluentd.conf +0 -1
  64. data/test/command/config/default/catalog.json +43 -0
  65. data/test/command/config/default/fluentd.conf +11 -0
  66. data/test/command/fixture/documents.jsons +208 -0
  67. data/test/command/fixture/user-table-array.jsons +38 -0
  68. data/test/command/fixture/user-table.jsons +38 -0
  69. data/test/command/run-test.rb +35 -0
  70. data/test/command/suite/add/minimum.expected +12 -0
  71. data/test/command/suite/add/minimum.test +11 -0
  72. data/test/command/suite/add/with-values.expected +12 -0
  73. data/test/command/suite/add/with-values.test +17 -0
  74. data/test/command/suite/add/without-key.expected +12 -0
  75. data/test/command/suite/add/without-key.test +16 -0
  76. data/test/command/suite/groonga/column_create/scalar.expected +34 -0
  77. data/test/command/suite/groonga/column_create/scalar.test +17 -0
  78. data/test/command/suite/groonga/column_create/vector.expected +34 -0
  79. data/test/command/suite/groonga/column_create/vector.test +18 -0
  80. data/test/command/suite/groonga/select/minimum.expected +26 -0
  81. data/test/command/suite/groonga/select/minimum.test +8 -0
  82. data/test/command/suite/groonga/table_create/array.expected +17 -0
  83. data/test/command/suite/groonga/table_create/array.test +8 -0
  84. data/test/command/suite/groonga/table_create/hash.expected +17 -0
  85. data/test/command/suite/groonga/table_create/hash.test +8 -0
  86. data/test/command/suite/search/array-attribute-label.expected +25 -0
  87. data/test/command/suite/search/array-attribute-label.test +30 -0
  88. data/test/command/suite/search/chained-queries.expected +45 -0
  89. data/test/command/suite/search/chained-queries.test +43 -0
  90. data/test/command/suite/search/complex.expected +52 -0
  91. data/test/command/suite/search/complex.test +25 -0
  92. data/test/command/suite/search/condition-nested.expected +19 -0
  93. data/test/command/suite/search/condition-nested.test +29 -0
  94. data/test/command/suite/search/condition-query.expected +28 -0
  95. data/test/command/suite/search/condition-query.test +25 -0
  96. data/test/command/suite/search/condition-script.expected +28 -0
  97. data/test/command/suite/search/condition-script.test +28 -0
  98. data/test/command/suite/search/hash-attribute-label.expected +34 -0
  99. data/test/command/suite/search/hash-attribute-label.test +38 -0
  100. data/test/command/suite/search/minimum.expected +13 -0
  101. data/test/command/suite/search/minimum.test +16 -0
  102. data/test/command/suite/search/multiple-queries.expected +39 -0
  103. data/test/command/suite/search/multiple-queries.test +39 -0
  104. data/test/command/suite/search/output-range.expected +28 -0
  105. data/test/command/suite/search/output-range.test +25 -0
  106. data/test/command/suite/search/simple.expected +52 -0
  107. data/test/command/suite/search/simple.test +24 -0
  108. data/test/command/suite/search/sort-and-output-range.expected +25 -0
  109. data/test/command/suite/search/sort-and-output-range.test +29 -0
  110. data/test/command/suite/search/sort-range.expected +28 -0
  111. data/test/command/suite/search/sort-range.test +28 -0
  112. data/test/command/suite/search/sort-with-invisible-column.expected +28 -0
  113. data/test/command/suite/search/sort-with-invisible-column.test +28 -0
  114. data/test/unit/fixtures/array.grn +18 -0
  115. data/test/{fixtures → unit/fixtures}/catalog.json +0 -0
  116. data/test/{fixtures → unit/fixtures}/document.grn +20 -9
  117. data/test/unit/fixtures/reference/array.grn +11 -0
  118. data/test/unit/fixtures/reference/hash.grn +7 -0
  119. data/test/{helper.rb → unit/helper.rb} +2 -1
  120. data/test/{helper → unit/helper}/fixture.rb +1 -1
  121. data/test/unit/helper/plugin_helper.rb +38 -0
  122. data/test/{helper → unit/helper}/sandbox.rb +19 -6
  123. data/test/{helper → unit/helper}/stub_worker.rb +1 -1
  124. data/test/{helper → unit/helper}/watch_helper.rb +1 -13
  125. data/test/{plugin → unit/plugin}/adapter/groonga/test_select.rb +108 -4
  126. data/test/unit/plugin/collector/test_basic.rb +558 -0
  127. data/test/unit/plugin/distributor/test_search.rb +914 -0
  128. data/test/{plugin → unit/plugin}/handler/groonga/test_column_create.rb +18 -14
  129. data/test/{plugin → unit/plugin}/handler/groonga/test_table_create.rb +13 -11
  130. data/test/{plugin/handler/test_handler_add.rb → unit/plugin/handler/test_add.rb} +2 -14
  131. data/test/{plugin/handler/test_handler_groonga.rb → unit/plugin/handler/test_groonga.rb} +6 -26
  132. data/test/unit/plugin/handler/test_search.rb +601 -0
  133. data/test/{plugin/handler/test_handler_watch.rb → unit/plugin/handler/test_watch.rb} +2 -2
  134. data/test/{run-test.rb → unit/run-test.rb} +3 -3
  135. data/test/{test_adapter.rb → unit/test_adapter.rb} +17 -14
  136. data/test/{test_catalog.rb → unit/test_catalog.rb} +4 -4
  137. data/test/{test_command_mapper.rb → unit/test_command_mapper.rb} +1 -1
  138. data/test/{test_groonga_command_converter.rb → unit/test_groonga_command_converter.rb} +3 -3
  139. data/test/{test_job_queue_schema.rb → unit/test_job_queue_schema.rb} +1 -1
  140. data/test/{test_output.rb → unit/test_output.rb} +9 -9
  141. data/test/{test_handler.rb → unit/test_plugin.rb} +19 -22
  142. data/test/unit/test_plugin_repository.rb +89 -0
  143. data/test/{test_sweeper.rb → unit/test_sweeper.rb} +1 -1
  144. data/test/{test_watch_schema.rb → unit/test_watch_schema.rb} +1 -1
  145. data/test/{test_watcher.rb → unit/test_watcher.rb} +1 -1
  146. metadata +226 -66
  147. data/lib/droonga/executor.rb +0 -289
  148. data/lib/droonga/plugin/handler_proxy.rb +0 -82
  149. data/test/plugin/handler/test_handler_search.rb +0 -512
  150. data/test/test_worker.rb +0 -144
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2013 droonga project
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
@@ -63,7 +63,7 @@ module Droonga
63
63
  @options[name]
64
64
  end
65
65
 
66
- def get_engines(name)
66
+ def get_partitions(name)
67
67
  device = @catalog["farms"][name]["device"]
68
68
  pattern = Regexp.new("^#{name}\.")
69
69
  results = {}
@@ -0,0 +1,107 @@
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/collector_plugin"
20
+
21
+ module Droonga
22
+ class Collector
23
+ include Pluggable
24
+
25
+ def initialize(id, dispatcher, components, tasks, inputs)
26
+ @id = id
27
+ @dispatcher = dispatcher
28
+ @components = components
29
+ @tasks = tasks
30
+ @n_dones = 0
31
+ @inputs = inputs
32
+ load_plugins(["basic"]) # TODO: make customizable
33
+ end
34
+
35
+ def handle(name, value)
36
+ tasks = @inputs[name]
37
+ unless tasks
38
+ #TODO: result arrived before its query
39
+ return
40
+ end
41
+ tasks.each do |task|
42
+ task["n_of_inputs"] += 1 if name
43
+ component = task["component"]
44
+ type = component["type"]
45
+ command = component["command"] || ("collector_" + type)
46
+ n_of_expects = component["n_of_expects"]
47
+ synchronous = nil
48
+ if command
49
+ synchronous = true unless n_of_expects.zero?
50
+ # TODO: check if asynchronous execution is available.
51
+ message = {
52
+ "task"=>task,
53
+ "name"=>name,
54
+ "value"=>value
55
+ }
56
+ unless synchronous
57
+ descendants = {}
58
+ component["descendants"].each do |name, indices|
59
+ descendants[name] = indices.collect do |index|
60
+ @components[index]["routes"].map do |route|
61
+ @dispatcher.farm_path(route)
62
+ end
63
+ end
64
+ end
65
+ message["descendants"] = descendants
66
+ message["id"] = @id
67
+ end
68
+ if @id == task["route"]
69
+ process(command, message)
70
+ else
71
+ @dispatcher.deliver(@id, task["route"], message, command, synchronous)
72
+ end
73
+ end
74
+ return if task["n_of_inputs"] < n_of_expects
75
+ #the task is done
76
+ if synchronous
77
+ result = task["values"]
78
+ post = component["post"]
79
+ @dispatcher.post(result, post) if post
80
+ component["descendants"].each do |name, indices|
81
+ message = {
82
+ "id" => @id,
83
+ "input" => name,
84
+ "value" => result[name]
85
+ }
86
+ indices.each do |index|
87
+ @components[index]["routes"].each do |route|
88
+ @dispatcher.dispatch(message, route)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ @n_dones += 1
94
+ @dispatcher.collectors.delete(@id) if @n_dones == @tasks.size
95
+ end
96
+ end
97
+
98
+ private
99
+ def instantiate_plugin(name)
100
+ CollectorPlugin.repository.instantiate(name, @dispatcher)
101
+ end
102
+
103
+ def log_tag
104
+ "collector"
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,82 @@
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 CollectorPlugin < Plugin
22
+ extend PluginRegisterable
23
+
24
+ attr_reader :task, :input_name, :component, :output_values, :body, :output_names
25
+ def initialize(dispatcher)
26
+ super()
27
+ @dispatcher = dispatcher
28
+ end
29
+
30
+ def process(command, message)
31
+ return false unless message.is_a? Hash
32
+ @task = message["task"]
33
+ return false unless @task.is_a? Hash
34
+ @component = @task["component"]
35
+ return false unless @component.is_a? Hash
36
+ @output_values = @task["values"]
37
+ @body = @component["body"]
38
+ @output_names = @component["outputs"]
39
+ @id = message["id"]
40
+ @value = message["value"]
41
+ @input_name = message["name"]
42
+ @descendants = message["descendants"]
43
+ super(command, @value)
44
+ output if @descendants
45
+ true
46
+ end
47
+
48
+ # TODO: consider better name
49
+ def emit(value, name=nil)
50
+ unless name
51
+ if @output_names
52
+ name = @output_names.first
53
+ else
54
+ @output_values = @task["values"] = value
55
+ return
56
+ end
57
+ end
58
+ @output_values[name] = value
59
+ end
60
+
61
+ def post(message, destination=nil)
62
+ @dispatcher.post(message, destination)
63
+ end
64
+
65
+ def output
66
+ result = @task["values"]
67
+ post(result, @component["post"]) if @component["post"]
68
+ @descendants.each do |name, dests|
69
+ message = {
70
+ "id" => @id,
71
+ "input" => name,
72
+ "value" => result[name]
73
+ }
74
+ dests.each do |routes|
75
+ routes.each do |route|
76
+ post(message, "to"=>route, "type"=>"dispatcher")
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2013 droonga project
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
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2013 droonga project
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
@@ -16,36 +16,94 @@
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
18
  require 'tsort'
19
- require "droonga/handler"
20
19
  require "droonga/adapter"
20
+ require "droonga/distributor"
21
21
  require "droonga/catalog"
22
+ require "droonga/collector"
23
+ require "droonga/farm"
24
+ require "droonga/input_message"
22
25
 
23
26
  module Droonga
24
- class Proxy
25
- attr_reader :collectors
26
- def initialize(worker, name)
27
- @engines = {}
28
- Droonga::catalog.get_engines(name).each do |name, options|
29
- engine = Droonga::Engine.new(options.merge(:proxy => false,
30
- :with_server => false))
31
- engine.start
32
- @engines[name] = engine
33
- end
34
- @worker = worker
35
- @name = name
27
+ class Dispatcher
28
+ attr_reader :name, :envelope, :collectors
29
+
30
+ def initialize(options)
31
+ @options = options
32
+ @name = @options[:name]
33
+ @farm = Farm.new(name)
36
34
  @collectors = {}
37
35
  @current_id = 0
38
36
  @local = Regexp.new("^#{@name}")
39
- plugins = ["proxy"] + (Droonga::catalog.option("plugins")||[]) + ["adapter"]
40
- plugins.each do |plugin|
41
- @worker.add_handler(plugin)
42
- end
37
+ @adapter = Adapter.new(self,
38
+ :adapters => Droonga.catalog.option("plugins"))
39
+ @forwarder = Forwarder.new
40
+ @distributor = Distributor.new(self, @options)
41
+ end
42
+
43
+ def start
44
+ @farm.start
43
45
  end
44
46
 
45
47
  def shutdown
46
- @engines.each do |name, engine|
47
- engine.shutdown
48
+ @forwarder.shutdown
49
+ @distributor.shutdown
50
+ @adapter.shutdown
51
+ @farm.shutdown
52
+ end
53
+
54
+ def add_route(route)
55
+ envelope["via"].push(route)
56
+ end
57
+
58
+ def handle_envelope(envelope)
59
+ @envelope = envelope
60
+ if envelope["type"] == "dispatcher"
61
+ handle(envelope["body"], envelope["arguments"])
62
+ else
63
+ process_input_message(envelope)
64
+ end
65
+ end
66
+
67
+ def post(body, destination=nil)
68
+ $log.trace("#{log_tag}: post: start")
69
+ route = nil
70
+ unless is_route?(destination)
71
+ route = envelope["via"].pop
72
+ destination = route
73
+ end
74
+ unless is_route?(destination)
75
+ destination = envelope["replyTo"]
76
+ end
77
+ command = nil
78
+ receiver = nil
79
+ arguments = nil
80
+ synchronous = nil
81
+ case destination
82
+ when String
83
+ command = destination
84
+ when Hash
85
+ command = destination["type"]
86
+ receiver = destination["to"]
87
+ arguments = destination["arguments"]
88
+ synchronous = destination["synchronous"]
89
+ end
90
+ if receiver
91
+ @forwarder.forward(envelope, body,
92
+ "type" => command,
93
+ "to" => receiver,
94
+ "arguments" => arguments)
95
+ else
96
+ if command == "dispatcher"
97
+ handle(body, arguments)
98
+ elsif @adapter.processable?(command)
99
+ @adapter.process(command, body, *arguments)
100
+ else
101
+ @distributor.distribute(envelope.merge("type" => command,
102
+ "body" => body))
103
+ end
48
104
  end
105
+ add_route(route) if route
106
+ $log.trace("#{log_tag}: post: done")
49
107
  end
50
108
 
51
109
  def handle(message, arguments)
@@ -87,7 +145,7 @@ module Droonga
87
145
  if local?(destination)
88
146
  handle_internal_message(message)
89
147
  else
90
- post(message, "to"=>farm_path(destination), "type"=>"proxy")
148
+ post(message, "to"=>farm_path(destination), "type"=>"dispatcher")
91
149
  end
92
150
  end
93
151
 
@@ -95,15 +153,11 @@ module Droonga
95
153
  if id == route
96
154
  post(message, "type" => type, "synchronous"=> synchronous)
97
155
  else
98
- envelope = @worker.envelope.merge("body" => message, "type" => type)
99
- @engines[route].emit('', Time.now.to_f, envelope, synchronous)
156
+ envelope = @envelope.merge("body" => message, "type" => type)
157
+ @farm.process(route, envelope, synchronous)
100
158
  end
101
159
  end
102
160
 
103
- def post(message, destination)
104
- @worker.post(message, destination)
105
- end
106
-
107
161
  def generate_id
108
162
  id = @current_id
109
163
  @current_id = id.succ
@@ -122,6 +176,34 @@ module Droonga
122
176
  route =~ @local
123
177
  end
124
178
 
179
+ private
180
+ def is_route?(route)
181
+ route.is_a?(String) || route.is_a?(Hash)
182
+ end
183
+
184
+ def apply_input_adapters(envelope)
185
+ adapted_envelope = envelope
186
+ loop do
187
+ input_message = InputMessage.new(adapted_envelope)
188
+ command = input_message.command
189
+ break unless @adapter.processable?(command)
190
+ @adapter.process(command, input_message)
191
+ new_command = input_message.command
192
+ adapted_envelope = input_message.adapted_envelope
193
+ break if command == new_command
194
+ end
195
+ adapted_envelope
196
+ end
197
+
198
+ def process_input_message(envelope)
199
+ adapted_envelope = apply_input_adapters(envelope)
200
+ @distributor.distribute(adapted_envelope)
201
+ end
202
+
203
+ def log_tag
204
+ "[#{Process.ppid}][#{Process.pid}] dispatcher"
205
+ end
206
+
125
207
  class Planner
126
208
  attr_reader :components
127
209
  class UndefinedInputError < StandardError
@@ -141,8 +223,8 @@ module Droonga
141
223
  end
142
224
 
143
225
  include TSort
144
- def initialize(proxy, components)
145
- @proxy = proxy
226
+ def initialize(dispatcher, components)
227
+ @dispatcher = dispatcher
146
228
  @components = components
147
229
  end
148
230
 
@@ -170,12 +252,12 @@ module Droonga
170
252
  dataset = component["dataset"]
171
253
  routes =
172
254
  if dataset
173
- Droonga::catalog.get_routes(dataset, component)
255
+ Droonga.catalog.get_routes(dataset, component)
174
256
  else
175
257
  local
176
258
  end
177
259
  routes.each do |route|
178
- destinations[@proxy.farm_path(route)] += 1
260
+ destinations[@dispatcher.farm_path(route)] += 1
179
261
  end
180
262
  component["routes"] = routes
181
263
  end
@@ -188,7 +270,7 @@ module Droonga
188
270
  inputs = {}
189
271
  @components.each do |component|
190
272
  component["routes"].each do |route|
191
- next unless @proxy.local?(route)
273
+ next unless @dispatcher.local?(route)
192
274
  task = {
193
275
  "route" => route,
194
276
  "component" => component,
@@ -202,8 +284,8 @@ module Droonga
202
284
  end
203
285
  end
204
286
  end
205
- collector = Collector.new(id, @proxy, @components, tasks, inputs)
206
- @proxy.collectors[id] = collector
287
+ collector = Collector.new(id, @dispatcher, @components, tasks, inputs)
288
+ @dispatcher.collectors[id] = collector
207
289
  return collector
208
290
  end
209
291
 
@@ -250,122 +332,5 @@ module Droonga
250
332
  end
251
333
  end
252
334
  end
253
-
254
- class Collector
255
- def initialize(id, proxy, components, tasks, inputs)
256
- @id = id
257
- @proxy = proxy
258
- @components = components
259
- @tasks = tasks
260
- @n_dones = 0
261
- @inputs = inputs
262
- end
263
-
264
- def handle(name, value)
265
- tasks = @inputs[name]
266
- unless tasks
267
- #TODO: result arrived before its query
268
- return
269
- end
270
- tasks.each do |task|
271
- task["n_of_inputs"] += 1 if name
272
- component = task["component"]
273
- type = component["type"]
274
- command = component["command"] || ("proxy_" + type)
275
- n_of_expects = component["n_of_expects"]
276
- synchronous = nil
277
- if command
278
- # TODO: should be controllable for each command respectively.
279
- synchronous = !n_of_expects.zero?
280
- # TODO: check if asynchronous execution is available.
281
- message = {
282
- "task"=>task,
283
- "name"=>name,
284
- "value"=>value
285
- }
286
- unless synchronous
287
- descendants = {}
288
- component["descendants"].each do |name, indices|
289
- descendants[name] = indices.collect do |index|
290
- @components[index]["routes"].map do |route|
291
- @proxy.farm_path(route)
292
- end
293
- end
294
- end
295
- message["descendants"] = descendants
296
- message["id"] = @id
297
- end
298
- @proxy.deliver(@id, task["route"], message, command, synchronous)
299
- end
300
- return if task["n_of_inputs"] < n_of_expects
301
- #the task is done
302
- if synchronous
303
- result = task["values"]
304
- post = component["post"]
305
- @proxy.post(result, post) if post
306
- component["descendants"].each do |name, indices|
307
- message = {
308
- "id" => @id,
309
- "input" => name,
310
- "value" => result[name]
311
- }
312
- indices.each do |index|
313
- @components[index]["routes"].each do |route|
314
- @proxy.dispatch(message, route)
315
- end
316
- end
317
- end
318
- end
319
- @n_dones += 1
320
- @proxy.collectors.delete(@id) if @n_dones == @tasks.size
321
- end
322
- end
323
- end
324
- end
325
-
326
- class ProxyMessageHandler < Droonga::Handler
327
- Droonga::HandlerPlugin.register("proxy_message", self)
328
- def initialize(*arguments)
329
- super
330
- @proxy = Droonga::Proxy.new(@worker, @worker.name)
331
- end
332
-
333
- def shutdown
334
- @proxy.shutdown
335
- end
336
-
337
- command :proxy
338
- def proxy(request, *arguments)
339
- @proxy.handle(request, arguments)
340
- end
341
-
342
- def prefer_synchronous?(command)
343
- return true
344
- end
345
- end
346
-
347
- class ProxyHandler < Droonga::Handler
348
- attr_reader :task, :input_name, :component, :output_values, :body, :output_names
349
- def handle(command, request, *arguments)
350
- return false unless request.is_a? Hash
351
- @task = request["task"]
352
- return false unless @task.is_a? Hash
353
- @component = @task["component"]
354
- return false unless @component.is_a? Hash
355
- @output_values = @task["values"]
356
- @body = @component["body"]
357
- @output_names = @component["outputs"]
358
- @id = request["id"]
359
- @value = request["value"]
360
- @input_name = request["name"]
361
- @descendants = request["descendants"]
362
- invoke(command, @value, *arguments)
363
- output if @descendants
364
- true
365
- end
366
-
367
- def prefer_synchronous?(command)
368
- return true
369
- end
370
335
  end
371
336
  end