fluent-plugin-droonga 0.0.2

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile +40 -0
  5. data/LICENSE.txt +14 -0
  6. data/README.md +18 -0
  7. data/Rakefile +25 -0
  8. data/benchmark/benchmark.rb +123 -0
  9. data/benchmark/utils.rb +243 -0
  10. data/benchmark/watch/benchmark-notify.rb +143 -0
  11. data/benchmark/watch/benchmark-notify.sh +19 -0
  12. data/benchmark/watch/benchmark-publish.rb +120 -0
  13. data/benchmark/watch/benchmark-scan.rb +210 -0
  14. data/benchmark/watch/catalog.json +32 -0
  15. data/benchmark/watch/fluentd.conf +12 -0
  16. data/bin/grn2jsons +85 -0
  17. data/fluent-plugin-droonga.gemspec +41 -0
  18. data/lib/droonga/adapter.rb +156 -0
  19. data/lib/droonga/catalog.rb +153 -0
  20. data/lib/droonga/command_mapper.rb +45 -0
  21. data/lib/droonga/engine.rb +83 -0
  22. data/lib/droonga/executor.rb +289 -0
  23. data/lib/droonga/handler.rb +140 -0
  24. data/lib/droonga/handler_plugin.rb +35 -0
  25. data/lib/droonga/job_queue.rb +83 -0
  26. data/lib/droonga/job_queue_schema.rb +65 -0
  27. data/lib/droonga/logger.rb +34 -0
  28. data/lib/droonga/plugin.rb +41 -0
  29. data/lib/droonga/plugin/adapter/groonga/select.rb +88 -0
  30. data/lib/droonga/plugin/adapter_groonga.rb +40 -0
  31. data/lib/droonga/plugin/handler/groonga/column_create.rb +103 -0
  32. data/lib/droonga/plugin/handler/groonga/table_create.rb +100 -0
  33. data/lib/droonga/plugin/handler_add.rb +44 -0
  34. data/lib/droonga/plugin/handler_forward.rb +70 -0
  35. data/lib/droonga/plugin/handler_groonga.rb +52 -0
  36. data/lib/droonga/plugin/handler_proxy.rb +82 -0
  37. data/lib/droonga/plugin/handler_search.rb +33 -0
  38. data/lib/droonga/plugin/handler_watch.rb +102 -0
  39. data/lib/droonga/proxy.rb +371 -0
  40. data/lib/droonga/searcher.rb +415 -0
  41. data/lib/droonga/server.rb +112 -0
  42. data/lib/droonga/sweeper.rb +42 -0
  43. data/lib/droonga/watch_schema.rb +88 -0
  44. data/lib/droonga/watcher.rb +256 -0
  45. data/lib/droonga/worker.rb +51 -0
  46. data/lib/fluent/plugin/out_droonga.rb +56 -0
  47. data/lib/groonga_command_converter.rb +137 -0
  48. data/sample/cluster/catalog.json +43 -0
  49. data/sample/cluster/fluentd.conf +12 -0
  50. data/sample/fluentd.conf +8 -0
  51. data/test/fixtures/catalog.json +43 -0
  52. data/test/fixtures/document.grn +23 -0
  53. data/test/helper.rb +24 -0
  54. data/test/helper/fixture.rb +28 -0
  55. data/test/helper/sandbox.rb +73 -0
  56. data/test/helper/stub_worker.rb +27 -0
  57. data/test/helper/watch_helper.rb +35 -0
  58. data/test/plugin/adapter/groonga/test_select.rb +176 -0
  59. data/test/plugin/handler/groonga/test_column_create.rb +127 -0
  60. data/test/plugin/handler/groonga/test_table_create.rb +140 -0
  61. data/test/plugin/handler/test_handler_add.rb +135 -0
  62. data/test/plugin/handler/test_handler_groonga.rb +64 -0
  63. data/test/plugin/handler/test_handler_search.rb +512 -0
  64. data/test/plugin/handler/test_handler_watch.rb +168 -0
  65. data/test/run-test.rb +55 -0
  66. data/test/test_adapter.rb +48 -0
  67. data/test/test_catalog.rb +59 -0
  68. data/test/test_command_mapper.rb +44 -0
  69. data/test/test_groonga_command_converter.rb +242 -0
  70. data/test/test_handler.rb +53 -0
  71. data/test/test_job_queue_schema.rb +45 -0
  72. data/test/test_output.rb +99 -0
  73. data/test/test_sweeper.rb +95 -0
  74. data/test/test_watch_schema.rb +57 -0
  75. data/test/test_watcher.rb +336 -0
  76. data/test/test_worker.rb +144 -0
  77. metadata +299 -0
@@ -0,0 +1,35 @@
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
+ module Droonga
19
+ class HandlerPlugin
20
+ @@plugins = {}
21
+ class << self
22
+ def register(name, handler_class)
23
+ @@plugins[name] = handler_class
24
+ end
25
+ end
26
+
27
+ def initialize(name)
28
+ @name = name
29
+ end
30
+
31
+ def instantiate(*args)
32
+ @@plugins[@name].new(*args)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,83 @@
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/job_queue_schema"
19
+ require "msgpack"
20
+
21
+ module Droonga
22
+ class JobQueue
23
+ class << self
24
+ def ensure_schema(database_path, queue_name)
25
+ schema = JobQueueSchema.new(database_path, queue_name)
26
+ schema.ensure_created
27
+ end
28
+
29
+ def open(database_path, queue_name)
30
+ job_queue = new(database_path, queue_name)
31
+ job_queue.open
32
+ job_queue
33
+ end
34
+ end
35
+
36
+ def initialize(database_path, queue_name)
37
+ @database_path = database_path
38
+ @queue_name = queue_name
39
+ end
40
+
41
+ def open
42
+ @context = Groonga::Context.new
43
+ @database = @context.open_database(@database_path)
44
+ @context.encoding = :none
45
+
46
+ @queue = @context[@queue_name]
47
+ end
48
+
49
+ def push_message(message)
50
+ $log.trace("#{log_tag}: push_message: start")
51
+ packed_message = message.to_msgpack
52
+ @queue.push do |record|
53
+ record.message = packed_message
54
+ end
55
+ $log.trace("#{log_tag}: push_message: done")
56
+ end
57
+
58
+ def pull_message
59
+ packed_message = nil
60
+ @queue.pull do |record|
61
+ if record
62
+ packed_message = record.message
63
+ record.delete
64
+ end
65
+ end
66
+ return nil unless packed_message
67
+ MessagePack.unpack(packed_message)
68
+ end
69
+
70
+ def close
71
+ @queue = nil
72
+ if @database
73
+ @database.close
74
+ @context.close
75
+ @database = @context = nil
76
+ end
77
+ end
78
+
79
+ def log_tag
80
+ "[#{Process.ppid}][#{Process.pid}] job_queue"
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,65 @@
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 "fileutils"
19
+
20
+ require "groonga"
21
+
22
+ module Droonga
23
+ class JobQueueSchema
24
+ def initialize(database_path, queue_name)
25
+ @database_path = database_path
26
+ @queue_name = queue_name
27
+ end
28
+
29
+ def ensure_created
30
+ ensure_database
31
+ ensure_queue
32
+ end
33
+
34
+ private
35
+ def ensure_database
36
+ return if File.exist?(@database_path)
37
+ FileUtils.mkdir_p(File.dirname(@database_path))
38
+ create_context do |context|
39
+ context.create_database(@database_path) do
40
+ end
41
+ end
42
+ end
43
+
44
+ def ensure_queue
45
+ create_context do |context|
46
+ context.open_database(@database_path) do
47
+ Groonga::Schema.define(:context => context) do |schema|
48
+ schema.create_table(@queue_name, :type => :array) do |table|
49
+ table.text("message")
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def create_context
57
+ context = Groonga::Context.new
58
+ begin
59
+ yield(context)
60
+ ensure
61
+ context.close
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,34 @@
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
+ 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, additional_information={})
28
+ if $log
29
+ $log.error(message, additional_information)
30
+ $log.error_backtrace
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,41 @@
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
+ module Droonga
19
+ class Plugin
20
+ class << self
21
+ def load_all
22
+ $LOAD_PATH.each do |load_path|
23
+ Dir.glob("#{load_path}/droonga/plugin/*_*.rb") do |path|
24
+ type, name = File.basename(path, ".rb").split(/_/, 2)
25
+ plugin = new(type, name)
26
+ plugin.load
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def initialize(type, name)
33
+ @type = type
34
+ @name = name
35
+ end
36
+
37
+ def load
38
+ require "droonga/plugin/#{@type}_#{@name}"
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright (C) 2013 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
+ class GroongaAdapter
18
+ class Select
19
+ def convert_request(select_request)
20
+ table = select_request["table"]
21
+ result_name = table + "_result"
22
+ match_columns = select_request["match_columns"]
23
+ match_to = match_columns
24
+ query = select_request["query"]
25
+ output_columns = select_request["output_columns"]
26
+ attributes = output_columns.split(/, */)
27
+
28
+ search_request = {
29
+ "queries" => {
30
+ result_name => {
31
+ "source" => table,
32
+ "output" => {
33
+ "elements" => [
34
+ "startTime",
35
+ "elapsedTime",
36
+ "count",
37
+ "attributes",
38
+ "records",
39
+ ],
40
+ "attributes" => attributes,
41
+ },
42
+ }
43
+ }
44
+ }
45
+ if query
46
+ condition = {
47
+ "query" => query,
48
+ "matchTo"=> match_to,
49
+ "defaultOperator"=> "&&",
50
+ "allowPragma"=> false,
51
+ "allowColumn"=> true,
52
+ }
53
+ search_request["queries"][result_name]["condition"] = condition
54
+ end
55
+ search_request
56
+ end
57
+
58
+ def convert_response(search_response)
59
+ select_responses = search_response.collect do |key, value|
60
+ status_code = 0
61
+
62
+ start_time = value["startTime"]
63
+ start_time_in_unix_time = if start_time
64
+ Time.parse(start_time).to_f
65
+ else
66
+ Time.now.to_f
67
+ end
68
+ elapsed_time = value["elapsedTime"] || 0
69
+ count = value["count"]
70
+
71
+ attributes = value["attributes"] || []
72
+ converted_attributes = attributes.collect do |attribute|
73
+ name = attribute["name"]
74
+ type = attribute["type"]
75
+ [name, type]
76
+ end
77
+
78
+ header = [status_code, start_time_in_unix_time, elapsed_time]
79
+ results = [[count], converted_attributes, value["records"]]
80
+ body = [results]
81
+
82
+ [header, body]
83
+ end
84
+ select_responses.first
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (C) 2013 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 "groonga"
17
+
18
+ require "droonga/adapter"
19
+
20
+ module Droonga
21
+ class GroongaAdapter < Droonga::Adapter
22
+ # TODO: AdapterPlugin or something should be defined to avoid conflicts.
23
+ Droonga::HandlerPlugin.register("select", self)
24
+ command :select
25
+ def select(select_request)
26
+ command = Select.new
27
+ search_request = command.convert_request(select_request)
28
+ add_route("select_response")
29
+ post(search_request, "search")
30
+ end
31
+
32
+ command :select_response
33
+ def select_response(search_response)
34
+ command = Select.new
35
+ emit(command.convert_response(search_response))
36
+ end
37
+ end
38
+ end
39
+
40
+ require "droonga/plugin/adapter/groonga/select"
@@ -0,0 +1,103 @@
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 "groonga"
19
+ require "groonga/command/column-create"
20
+
21
+ module Droonga
22
+ class GroongaHandler
23
+ class ColumnCreate
24
+ def initialize(context)
25
+ @context = context
26
+ end
27
+
28
+ def execute(request)
29
+ command_class = Groonga::Command.find("column_create")
30
+ @command = command_class.new("column_create", request)
31
+
32
+ if @command.column_index?
33
+ define_index
34
+ else
35
+ define_column
36
+ end
37
+ end
38
+
39
+ private
40
+ def define_column
41
+ table_name = @command["table"]
42
+ column_name = @command["name"]
43
+ column_type = @command["type"]
44
+
45
+ options = create_column_options
46
+ Groonga::Schema.define(:context => @context) do |schema|
47
+ schema.change_table(table_name) do |table|
48
+ table.column(column_name, column_type, options)
49
+ end
50
+ end
51
+ [true]
52
+ end
53
+
54
+ def create_column_options
55
+ options = {}
56
+ create_column_options_flags(options)
57
+ options
58
+ end
59
+
60
+ def create_column_options_flags(options)
61
+ options[:type] = :scalar
62
+ if @command.column_scalar?
63
+ options[:type] = :scalar
64
+ elsif @command.column_vector?
65
+ options[:type] = :vector
66
+ end
67
+ options
68
+ end
69
+
70
+ def define_index
71
+ table_name = @command["table"]
72
+ target_table = @command["type"]
73
+ target_column = @command["source"]
74
+
75
+ options = create_index_options
76
+ Groonga::Schema.define(:context => @context) do |schema|
77
+ schema.change_table(table_name) do |table|
78
+ table.index("#{target_table}.#{target_column}", options)
79
+ end
80
+ end
81
+ [true]
82
+ end
83
+
84
+ def create_index_options
85
+ options = {}
86
+ create_index_options_name(options)
87
+ create_index_options_flags(options)
88
+ options
89
+ end
90
+
91
+ def create_index_options_name(options)
92
+ options[:name] = @command["name"]
93
+ end
94
+
95
+ def create_index_options_flags(options)
96
+ options[:with_section] = true if @command.with_section?
97
+ options[:with_weight] = true if @command.with_weight?
98
+ options[:with_position] = true if @command.with_position?
99
+ options
100
+ end
101
+ end
102
+ end
103
+ end