droonga-engine 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/bin/droonga-engine-absorb-data +200 -86
  4. data/bin/droonga-engine-configure +14 -11
  5. data/bin/droonga-engine-join +178 -59
  6. data/droonga-engine.gemspec +1 -1
  7. data/install.sh +1 -0
  8. data/lib/droonga/buffered_tcp_socket.rb +2 -2
  9. data/lib/droonga/catalog/base.rb +18 -0
  10. data/lib/droonga/catalog/dataset.rb +8 -0
  11. data/lib/droonga/catalog/version1.rb +3 -12
  12. data/lib/droonga/catalog/version2.rb +5 -12
  13. data/lib/droonga/command/droonga_engine.rb +6 -61
  14. data/lib/droonga/command/droonga_engine_service.rb +1 -0
  15. data/lib/droonga/command/droonga_engine_worker.rb +1 -0
  16. data/lib/droonga/command/remote.rb +18 -1
  17. data/lib/droonga/command/serf_event_handler.rb +3 -0
  18. data/lib/droonga/data_absorber.rb +234 -44
  19. data/lib/droonga/distributed_command_planner.rb +5 -5
  20. data/lib/droonga/engine.rb +27 -15
  21. data/lib/droonga/engine/version.rb +1 -1
  22. data/lib/droonga/handler_runner.rb +4 -0
  23. data/lib/droonga/node_status.rb +6 -2
  24. data/lib/droonga/path.rb +8 -14
  25. data/lib/droonga/planner.rb +4 -3
  26. data/lib/droonga/plugin/metadata/handler_action.rb +8 -0
  27. data/lib/droonga/plugins/groonga/column_create.rb +1 -1
  28. data/lib/droonga/plugins/groonga/column_list.rb +23 -1
  29. data/lib/droonga/plugins/groonga/column_remove.rb +1 -1
  30. data/lib/droonga/plugins/groonga/column_rename.rb +1 -1
  31. data/lib/droonga/plugins/groonga/delete.rb +1 -1
  32. data/lib/droonga/plugins/groonga/select.rb +17 -2
  33. data/lib/droonga/plugins/groonga/table_create.rb +26 -1
  34. data/lib/droonga/plugins/groonga/table_remove.rb +1 -1
  35. data/lib/droonga/plugins/search.rb +1 -1
  36. data/lib/droonga/plugins/search/distributed_search_planner.rb +15 -7
  37. data/lib/droonga/processor.rb +3 -2
  38. data/lib/droonga/searcher.rb +31 -15
  39. data/lib/droonga/serf.rb +1 -0
  40. data/lib/droonga/service_installation.rb +2 -2
  41. data/lib/droonga/single_step.rb +2 -2
  42. data/test/command/fixture/event.jsons +3 -2
  43. data/test/command/fixture/user-table.jsons +3 -2
  44. data/test/command/fixture/users.jsons +25 -0
  45. data/test/command/run-test.rb +13 -1
  46. data/test/command/suite/groonga/column_create/scalar.test +3 -2
  47. data/test/command/suite/groonga/column_create/vector.test +3 -2
  48. data/test/command/suite/groonga/column_list/{success.expected → no-key.expected} +0 -0
  49. data/test/command/suite/groonga/column_list/{success.test → no-key.test} +1 -1
  50. data/test/command/suite/groonga/column_list/with-key.expected +96 -0
  51. data/test/command/suite/groonga/column_list/with-key.test +25 -0
  52. data/test/command/suite/groonga/column_remove/success.test +3 -2
  53. data/test/command/suite/groonga/column_remove/unknown-column.test +3 -2
  54. data/test/command/suite/groonga/column_rename/success.test +3 -2
  55. data/test/command/suite/groonga/column_rename/unknown-column.test +3 -2
  56. data/test/command/suite/groonga/delete/duplicated-identifiers.test +3 -2
  57. data/test/command/suite/groonga/delete/no-identifier.test +3 -2
  58. data/test/command/suite/groonga/select/output_columns/default/array.expected +33 -0
  59. data/test/command/suite/groonga/select/output_columns/default/array.test +38 -0
  60. data/test/command/suite/groonga/select/output_columns/nonexistent.expected +28 -0
  61. data/test/command/suite/groonga/select/output_columns/nonexistent.test +26 -0
  62. data/test/command/suite/groonga/table_create/dat-without-key-type.expected +14 -0
  63. data/test/command/suite/groonga/table_create/dat-without-key-type.test +8 -0
  64. data/test/command/suite/groonga/table_create/dat.expected +13 -0
  65. data/test/command/suite/groonga/table_create/dat.test +9 -0
  66. data/test/command/suite/groonga/table_create/hash-without-key-type.expected +14 -0
  67. data/test/command/suite/groonga/table_create/hash-without-key-type.test +8 -0
  68. data/test/command/suite/groonga/table_create/hash.test +3 -2
  69. data/test/command/suite/groonga/table_create/pat-without-key-type.expected +14 -0
  70. data/test/command/suite/groonga/table_create/pat-without-key-type.test +8 -0
  71. data/test/command/suite/groonga/table_create/pat.expected +13 -0
  72. data/test/command/suite/groonga/table_create/pat.test +9 -0
  73. data/test/command/suite/groonga/table_list/success.test +3 -2
  74. data/test/unit/catalog/test_version1.rb +2 -2
  75. data/test/unit/catalog/test_version2.rb +3 -3
  76. data/test/unit/helper.rb +2 -2
  77. data/test/unit/helper/distributed_search_planner_helper.rb +9 -1
  78. data/test/unit/plugins/groonga/select/test_adapter_input.rb +15 -2
  79. data/test/unit/plugins/groonga/test_column_list.rb +119 -4
  80. data/test/unit/plugins/groonga/test_table_create.rb +29 -0
  81. data/test/unit/plugins/search/planner/test_basic.rb +2 -2
  82. data/test/unit/plugins/search/test_planner.rb +10 -2
  83. metadata +43 -8
@@ -37,7 +37,7 @@ module Droonga
37
37
  end
38
38
 
39
39
  class Handler < Droonga::Handler
40
- action.synchronous = true
40
+ action.change_schema = true
41
41
 
42
42
  def handle(message)
43
43
  command = Command.new(@context)
@@ -25,7 +25,7 @@ module Droonga
25
25
 
26
26
  class Planner < Droonga::Planner
27
27
  def plan(message)
28
- planner = DistributedSearchPlanner.new(message)
28
+ planner = DistributedSearchPlanner.new(@dataset, message)
29
29
  planner.plan
30
30
  end
31
31
  end
@@ -22,7 +22,7 @@ module Droonga
22
22
  module Plugins
23
23
  module Search
24
24
  class DistributedSearchPlanner < DistributedCommandPlanner
25
- def initialize(search_request_message)
25
+ def initialize(dataset, search_request_message)
26
26
  super
27
27
 
28
28
  @request = @source_message["body"]
@@ -43,7 +43,6 @@ module Droonga
43
43
  transform_query(input_name, query)
44
44
  end
45
45
 
46
- @dataset = @source_message["dataset"] || @request["dataset"]
47
46
  broadcast(:body => @request)
48
47
 
49
48
  super
@@ -79,7 +78,7 @@ module Droonga
79
78
  def transform_query(input_name, query)
80
79
  return unless need_reduce?(query)
81
80
 
82
- transformer = QueryTransformer.new(query)
81
+ transformer = QueryTransformer.new(@dataset, query)
83
82
  elements = transformer.mappers
84
83
  mapper = {}
85
84
  mapper["elements"] = elements unless elements.empty?
@@ -103,7 +102,8 @@ module Droonga
103
102
  class QueryTransformer
104
103
  attr_reader :reducers, :mappers
105
104
 
106
- def initialize(query)
105
+ def initialize(dataset, query)
106
+ @dataset = dataset
107
107
  @query = query
108
108
  @output = @query["output"]
109
109
  @reducers = {}
@@ -210,10 +210,14 @@ module Droonga
210
210
  end
211
211
 
212
212
  def final_offset
213
+ return @original_output_offset if @dataset.single_slice?
214
+
213
215
  @original_sort_offset + @original_output_offset
214
216
  end
215
217
 
216
218
  def final_limit
219
+ return @original_output_limit if @dataset.single_slice?
220
+
217
221
  if @original_sort_limit == UNLIMITED and
218
222
  @original_output_limit == UNLIMITED
219
223
  UNLIMITED
@@ -247,13 +251,17 @@ module Droonga
247
251
  "type" => "sum",
248
252
  }
249
253
  if unifiable?
250
- @query["sortBy"]["limit"] = -1 if @query["sortBy"].is_a?(Hash)
251
- @output["limit"] = -1
254
+ unless @dataset.single_slice?
255
+ if @query["sortBy"].is_a?(Hash)
256
+ @query["sortBy"]["limit"] = UNLIMITED
257
+ end
258
+ @output["limit"] = UNLIMITED
259
+ end
252
260
  mapper = {
253
261
  "target" => "records",
254
262
  }
255
263
  unless @output["elements"].include?("records")
256
- @records_limit = -1
264
+ @records_limit = UNLIMITED unless @dataset.single_slice?
257
265
  @output["elements"] << "records"
258
266
  @output["attributes"] ||= ["_key"]
259
267
  @output_records = false
@@ -44,9 +44,10 @@ module Droonga
44
44
  if @handler_runner.processable?(type)
45
45
  logger.trace("process: handlable: #{type}")
46
46
  synchronous = @handler_runner.prefer_synchronous?(type)
47
- if @n_workers.zero? or synchronous
47
+ change_schema = @handler_runner.change_schema?(type)
48
+ if @n_workers.zero? or synchronous or change_schema
48
49
  @handler_runner.process(message)
49
- if synchronous
50
+ if change_schema
50
51
  @job_pusher.broadcast(database_reopen_message)
51
52
  end
52
53
  else
@@ -462,14 +462,16 @@ module Droonga
462
462
  sub_record_table = table.range
463
463
  sub_attributes = format(attribute[:attributes], sub_record_table)
464
464
 
465
- format_attribute_subrecs(label, sub_attributes)
465
+ yield(format_attribute_subrecs(label, sub_attributes))
466
466
  else
467
467
  expression = attribute[:expression]
468
468
  if expression
469
- format_attribute_expression(label, expression)
469
+ yield(format_attribute_expression(label, expression))
470
470
  else
471
471
  column = table.column(source)
472
- format_attribute_column(label, column)
472
+ if column
473
+ yield(format_attribute_column(label, column))
474
+ end
473
475
  end
474
476
  end
475
477
  end
@@ -495,9 +497,13 @@ module Droonga
495
497
  end
496
498
 
497
499
  def format(attributes, table)
498
- attributes.collect do |attribute|
499
- format_attribute(attribute, table)
500
+ formatted_attributes = []
501
+ attributes.each do |attribute|
502
+ format_attribute(attribute, table) do |formatted_attribute|
503
+ formatted_attributes << formatted_attribute
504
+ end
500
505
  end
506
+ formatted_attributes
501
507
  end
502
508
  end
503
509
 
@@ -522,9 +528,10 @@ module Droonga
522
528
  def format(attributes, table)
523
529
  formatted_attributes = {}
524
530
  attributes.each do |attribute|
525
- formatted_attribute = format_attribute(attribute, table)
526
- attribute_name = attribute[:label]
527
- formatted_attributes[attribute_name] = formatted_attribute
531
+ format_attribute(attribute, table) do |formatted_attribute|
532
+ attribute_name = attribute[:label]
533
+ formatted_attributes[attribute_name] = formatted_attribute
534
+ end
528
535
  end
529
536
  formatted_attributes
530
537
  end
@@ -547,25 +554,28 @@ module Droonga
547
554
 
548
555
  private
549
556
  def record_value(record, attribute)
550
- if attribute[:source] == "_subrecs"
557
+ source = attribute[:source]
558
+ if source == "_subrecs"
551
559
  if record.table.is_a?(Groonga::Array)
552
560
  target_record = record.value
553
561
  else
554
562
  target_record = record
555
563
  end
556
- target_record.sub_records.collect do |sub_record|
564
+ values = target_record.sub_records.collect do |sub_record|
557
565
  sub_attributes = attribute[:attributes]
558
566
  format_record(sub_attributes, sub_record)
559
567
  end
568
+ yield(values)
560
569
  else
561
570
  expression = attribute[:expression]
562
571
  if expression
563
572
  variable = attribute[:variable]
564
573
  variable.value = record
565
- expression.execute
574
+ yield(expression.execute)
566
575
  else
567
- column_value = record[attribute[:source]]
568
- format_column_value(column_value)
576
+ return unless record.have_column?(source)
577
+ column_value = record[source]
578
+ yield(format_column_value(column_value))
569
579
  end
570
580
  end
571
581
  end
@@ -589,9 +599,13 @@ module Droonga
589
599
 
590
600
  private
591
601
  def format_record(attributes, record)
602
+ formatted_record = []
592
603
  attributes.collect do |attribute|
593
- record_value(record, attribute)
604
+ record_value(record, attribute) do |formatted_value|
605
+ formatted_record << formatted_value
606
+ end
594
607
  end
608
+ formatted_record
595
609
  end
596
610
  end
597
611
 
@@ -602,7 +616,9 @@ module Droonga
602
616
  def format_record(attributes, record)
603
617
  values = {}
604
618
  attributes.each do |attribute|
605
- values[attribute[:label]] = record_value(record, attribute)
619
+ record_value(record, attribute) do |formatted_value|
620
+ values[attribute[:label]] = formatted_value
621
+ end
606
622
  end
607
623
  values
608
624
  end
data/lib/droonga/serf.rb CHANGED
@@ -70,6 +70,7 @@ module Droonga
70
70
  "-bind", "#{extract_host(@name)}:#{port}",
71
71
  "-event-handler", "droonga-engine-serf-event-handler",
72
72
  "-log-level", log_level,
73
+ "-tag", "role=engine",
73
74
  *retry_joins)
74
75
  logger.trace("start: done")
75
76
  end
@@ -75,13 +75,13 @@ module Droonga
75
75
 
76
76
  def installed_as_service?
77
77
  return false unless user_exist?
78
-
78
+
79
79
  #TODO: we should support systemd also...
80
80
  succeeded = system("service", "droonga-engine", "status",
81
81
  :out => "/dev/null",
82
82
  :err => "/dev/null")
83
83
  return true if succeeded
84
-
84
+
85
85
  #TODO: we should support systemd also...
86
86
  result = `service droonga-engine status`
87
87
  result.include?("running") or \
@@ -26,12 +26,12 @@ module Droonga
26
26
  def plan(message)
27
27
  if message["type"] == "search"
28
28
  # XXX: workaround
29
- planner = Plugins::Search::Planner.new
29
+ planner = Plugins::Search::Planner.new(@dataset)
30
30
  return planner.plan(message)
31
31
  end
32
32
 
33
33
  # XXX: Re-implement me.
34
- planner = Planner.new
34
+ planner = Planner.new(@dataset)
35
35
  options = {}
36
36
  options[:write] = @definition.write?
37
37
  collector_class = @definition.collector_class
@@ -3,8 +3,9 @@
3
3
  "type": "table_create",
4
4
  "dataset": "Default",
5
5
  "body": {
6
- "name" : "Event",
7
- "flags" : "TABLE_HASH_KEY"
6
+ "name" : "Event",
7
+ "flags" : "TABLE_HASH_KEY",
8
+ "key_type" : "ShortText"
8
9
  }
9
10
  }
10
11
  {
@@ -3,8 +3,9 @@
3
3
  "type": "table_create",
4
4
  "dataset": "Default",
5
5
  "body": {
6
- "name" : "User",
7
- "flags" : "TABLE_PAT_KEY"
6
+ "name" : "User",
7
+ "flags" : "TABLE_PAT_KEY",
8
+ "key_type" : "ShortText"
8
9
  }
9
10
  }
10
11
  {
@@ -0,0 +1,25 @@
1
+ #@include fixture/user-table.jsons
2
+ #@disable-logging
3
+ {
4
+ "dataset": "Default",
5
+ "type": "add",
6
+ "body": {
7
+ "table": "User",
8
+ "key": "Alice",
9
+ "values": {
10
+ "name": "Alice"
11
+ }
12
+ }
13
+ }
14
+ {
15
+ "dataset": "Default",
16
+ "type": "add",
17
+ "body": {
18
+ "table": "User",
19
+ "key": "Bob",
20
+ "values": {
21
+ "name": "Bob"
22
+ }
23
+ }
24
+ }
25
+ #@enable-logging
@@ -18,6 +18,19 @@
18
18
  require "rbconfig"
19
19
  require "fileutils"
20
20
 
21
+ def system_serf_exist?
22
+ system("serf", "version",
23
+ :out => "/dev/null",
24
+ :err => "/dev/null")
25
+ end
26
+
27
+ unless system_serf_exist?
28
+ puts("Serf is not installed to your system.")
29
+ puts("Install Serf before running this test.")
30
+ puts("See: http://www.serfdom.io/")
31
+ exit(false)
32
+ end
33
+
21
34
  def run(*command_line)
22
35
  return if system(*command_line)
23
36
  puts("failed to run: #{command_line.join(' ')}")
@@ -29,7 +42,6 @@ lib_dir = File.expand_path(File.join(base_dir, "..", "..", "lib"))
29
42
 
30
43
  drntest_options = []
31
44
  drntest_options.concat(["--base-path", base_dir])
32
- drntest_options.concat(["--droonga-engine-options", "--no-orchestration"])
33
45
  drntest_options.concat(ARGV)
34
46
 
35
47
  run("bundle", "exec", "drntest", *drntest_options)
@@ -2,8 +2,9 @@
2
2
  "type": "table_create",
3
3
  "dataset": "Default",
4
4
  "body": {
5
- "name" : "User",
6
- "flags" : "TABLE_PAT_KEY"
5
+ "name" : "User",
6
+ "flags" : "TABLE_PAT_KEY",
7
+ "key_type" : "ShortText"
7
8
  }
8
9
  }
9
10
  {
@@ -2,8 +2,9 @@
2
2
  "type": "table_create",
3
3
  "dataset": "Default",
4
4
  "body": {
5
- "name" : "User",
6
- "flags" : "TABLE_PAT_KEY"
5
+ "name" : "User",
6
+ "flags" : "TABLE_PAT_KEY",
7
+ "key_type" : "ShortText"
7
8
  }
8
9
  }
9
10
  {
@@ -3,7 +3,7 @@
3
3
  "dataset": "Default",
4
4
  "body": {
5
5
  "name" : "User",
6
- "flags" : "TABLE_PAT_KEY"
6
+ "flags" : "TABLE_NO_KEY"
7
7
  }
8
8
  }
9
9
  {
@@ -0,0 +1,96 @@
1
+ {
2
+ "inReplyTo": "request-id",
3
+ "statusCode": 200,
4
+ "type": "table_create.result",
5
+ "body": [
6
+ [
7
+ 0,
8
+ 0.0,
9
+ 0.0
10
+ ],
11
+ true
12
+ ]
13
+ }
14
+ {
15
+ "inReplyTo": "request-id",
16
+ "statusCode": 200,
17
+ "type": "column_create.result",
18
+ "body": [
19
+ [
20
+ 0,
21
+ 0.0,
22
+ 0.0
23
+ ],
24
+ true
25
+ ]
26
+ }
27
+ {
28
+ "inReplyTo": "request-id",
29
+ "statusCode": 200,
30
+ "type": "column_list.result",
31
+ "body": [
32
+ [
33
+ 0,
34
+ 0.0,
35
+ 0.0
36
+ ],
37
+ [
38
+ [
39
+ [
40
+ "id",
41
+ "UInt32"
42
+ ],
43
+ [
44
+ "name",
45
+ "ShortText"
46
+ ],
47
+ [
48
+ "path",
49
+ "ShortText"
50
+ ],
51
+ [
52
+ "type",
53
+ "ShortText"
54
+ ],
55
+ [
56
+ "flags",
57
+ "ShortText"
58
+ ],
59
+ [
60
+ "domain",
61
+ "ShortText"
62
+ ],
63
+ [
64
+ "range",
65
+ "ShortText"
66
+ ],
67
+ [
68
+ "source",
69
+ "ShortText"
70
+ ]
71
+ ],
72
+ [
73
+ 256,
74
+ "_key",
75
+ "",
76
+ "",
77
+ "COLUMN_SCALAR",
78
+ "User",
79
+ "ShortText",
80
+ []
81
+ ],
82
+ [
83
+ 257,
84
+ "age",
85
+ "/path/to/column",
86
+ "fix",
87
+ "COLUMN_SCALAR",
88
+ "User",
89
+ "Int32",
90
+ [
91
+
92
+ ]
93
+ ]
94
+ ]
95
+ ]
96
+ }