droonga-engine 1.0.2 → 1.0.3

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 (203) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +7 -0
  5. data/Rakefile +6 -2
  6. data/bin/droonga-engine +2 -2
  7. data/bin/{droonga-catalog-generate → droonga-engine-catalog-generate} +15 -3
  8. data/bin/droonga-engine-serf-event-handler +20 -0
  9. data/bin/droonga-engine-service +2 -2
  10. data/doc/text/news.md +21 -1
  11. data/droonga-engine.gemspec +5 -2
  12. data/lib/droonga/catalog/collection_volume.rb +12 -0
  13. data/lib/droonga/catalog/dataset.rb +25 -0
  14. data/lib/droonga/catalog/single_volume.rb +10 -0
  15. data/lib/droonga/catalog/slice.rb +4 -0
  16. data/lib/droonga/catalog/version1.rb +59 -48
  17. data/lib/droonga/catalog/version2.rb +10 -20
  18. data/lib/droonga/catalog/volume_collection.rb +27 -4
  19. data/lib/droonga/catalog_generator.rb +12 -5
  20. data/lib/droonga/catalog_observer.rb +17 -35
  21. data/lib/droonga/command/droonga_engine.rb +436 -0
  22. data/lib/droonga/command/droonga_engine_service.rb +273 -0
  23. data/lib/droonga/command/serf_event_handler.rb +85 -0
  24. data/lib/droonga/dispatcher.rb +8 -8
  25. data/lib/droonga/engine.rb +90 -26
  26. data/lib/droonga/engine/version.rb +1 -1
  27. data/lib/droonga/engine_state.rb +29 -3
  28. data/lib/droonga/internal_fluent_message_receiver.rb +100 -0
  29. data/lib/droonga/live_nodes_list_loader.rb +48 -0
  30. data/lib/droonga/live_nodes_list_observer.rb +72 -0
  31. data/lib/droonga/path.rb +47 -0
  32. data/lib/droonga/plugins/dump.rb +279 -38
  33. data/lib/droonga/plugins/groonga/select.rb +26 -14
  34. data/lib/droonga/plugins/search.rb +30 -2
  35. data/lib/droonga/plugins/search/distributed_search_planner.rb +28 -11
  36. data/lib/droonga/processor.rb +4 -0
  37. data/lib/droonga/searcher.rb +26 -0
  38. data/lib/droonga/serf.rb +119 -0
  39. data/lib/droonga/serf_downloader.rb +90 -0
  40. data/lib/droonga/server.rb +2 -2
  41. data/lib/droonga/service_control_protocol.rb +26 -0
  42. data/sample/cluster/catalog.json +1 -1
  43. data/test/command/config/default/catalog.json +2 -2
  44. data/test/command/config/version1/catalog.json +1 -1
  45. data/test/command/fixture/documents.jsons +18 -18
  46. data/test/command/fixture/event.jsons +4 -4
  47. data/test/command/fixture/user-table-array.jsons +4 -4
  48. data/test/command/fixture/user-table.jsons +5 -5
  49. data/test/command/suite/add/dimension/column.catalog.json +1 -1
  50. data/test/command/suite/add/dimension/column.test +4 -4
  51. data/test/command/suite/add/dimension/integer.catalog.json +1 -1
  52. data/test/command/suite/add/dimension/integer.test +4 -4
  53. data/test/command/suite/add/error/invalid-integer.test +1 -1
  54. data/test/command/suite/add/error/invalid-time.test +1 -1
  55. data/test/command/suite/add/error/missing-key.test +1 -1
  56. data/test/command/suite/add/error/missing-table.test +1 -1
  57. data/test/command/suite/add/error/unknown-column.test +1 -1
  58. data/test/command/suite/add/error/unknown-table.test +1 -1
  59. data/test/command/suite/add/minimum.test +1 -1
  60. data/test/command/suite/add/vector/short_text.catalog.json +26 -0
  61. data/test/command/suite/add/vector/short_text.expected +42 -0
  62. data/test/command/suite/add/vector/short_text.test +35 -0
  63. data/test/command/suite/add/with-values.test +1 -1
  64. data/test/command/suite/add/without-key.test +1 -1
  65. data/test/command/suite/dump/column/index.catalog.json +40 -0
  66. data/test/command/suite/dump/column/index.expected +195 -0
  67. data/test/command/suite/dump/column/index.test +5 -0
  68. data/test/command/suite/dump/column/scalar.catalog.json +19 -0
  69. data/test/command/suite/dump/column/scalar.expected +99 -0
  70. data/test/command/suite/dump/column/scalar.test +5 -0
  71. data/test/command/suite/dump/column/vector.catalog.json +22 -0
  72. data/test/command/suite/dump/column/vector.expected +108 -0
  73. data/test/command/suite/dump/column/vector.test +5 -0
  74. data/test/command/suite/dump/record/vector/reference.catalog.json +27 -0
  75. data/test/command/suite/dump/record/vector/reference.expected +213 -0
  76. data/test/command/suite/dump/record/vector/reference.test +21 -0
  77. data/test/command/suite/dump/table/array.catalog.json +13 -0
  78. data/test/command/suite/dump/table/array.expected +63 -0
  79. data/test/command/suite/dump/table/array.test +5 -0
  80. data/test/command/suite/dump/table/double_array_trie.catalog.json +14 -0
  81. data/test/command/suite/dump/table/double_array_trie.expected +66 -0
  82. data/test/command/suite/dump/table/double_array_trie.test +5 -0
  83. data/test/command/suite/dump/table/hash.catalog.json +14 -0
  84. data/test/command/suite/dump/table/hash.expected +66 -0
  85. data/test/command/suite/dump/table/hash.test +5 -0
  86. data/test/command/suite/dump/table/patricia_trie.catalog.json +14 -0
  87. data/test/command/suite/dump/table/patricia_trie.expected +66 -0
  88. data/test/command/suite/dump/table/patricia_trie.test +5 -0
  89. data/test/command/suite/groonga/column_create/scalar.test +2 -2
  90. data/test/command/suite/groonga/column_create/unknown-table.test +1 -1
  91. data/test/command/suite/groonga/column_create/vector.test +2 -2
  92. data/test/command/suite/groonga/column_list/success.test +3 -3
  93. data/test/command/suite/groonga/column_list/unknown-table.test +1 -1
  94. data/test/command/suite/groonga/column_remove/success.test +3 -3
  95. data/test/command/suite/groonga/column_remove/unknown-column.test +2 -2
  96. data/test/command/suite/groonga/column_remove/unknown-table.test +1 -1
  97. data/test/command/suite/groonga/column_rename/success.test +3 -3
  98. data/test/command/suite/groonga/column_rename/unknown-column.test +2 -2
  99. data/test/command/suite/groonga/column_rename/unknown-table.test +1 -1
  100. data/test/command/suite/groonga/delete/duplicated-identifiers.test +2 -2
  101. data/test/command/suite/groonga/delete/filter.test +2 -2
  102. data/test/command/suite/groonga/delete/invalid-filter.test +1 -1
  103. data/test/command/suite/groonga/delete/no-identifier.test +2 -2
  104. data/test/command/suite/groonga/delete/success.test +2 -2
  105. data/test/command/suite/groonga/delete/unknown-table.test +1 -1
  106. data/test/command/suite/groonga/select/minimum.expected +24 -1
  107. data/test/command/suite/groonga/select/minimum.test +1 -1
  108. data/test/command/suite/groonga/select/type/time.catalog.json +19 -0
  109. data/test/command/suite/groonga/select/type/time.expected +37 -0
  110. data/test/command/suite/groonga/select/type/time.test +35 -0
  111. data/test/command/suite/groonga/table_create/array.test +1 -1
  112. data/test/command/suite/groonga/table_create/hash.test +1 -1
  113. data/test/command/suite/groonga/table_list/success.test +2 -2
  114. data/test/command/suite/groonga/table_remove/success.test +1 -1
  115. data/test/command/suite/groonga/table_remove/unknown-table.test +1 -1
  116. data/test/command/suite/message/error/unknown-type.expected +1 -1
  117. data/test/command/suite/message/error/unknown-type.test +1 -1
  118. data/test/command/suite/search/adjusters/multiple.catalog.json +1 -1
  119. data/test/command/suite/search/adjusters/multiple.test +3 -3
  120. data/test/command/suite/search/adjusters/one.catalog.json +1 -1
  121. data/test/command/suite/search/adjusters/one.test +3 -3
  122. data/test/command/suite/search/attributes/array.expected +7 -0
  123. data/test/command/suite/search/attributes/array.test +1 -1
  124. data/test/command/suite/search/attributes/hash.expected +18 -0
  125. data/test/command/suite/search/attributes/hash.test +1 -1
  126. data/test/command/suite/search/complex.expected +12 -0
  127. data/test/command/suite/search/complex.test +1 -1
  128. data/test/command/suite/search/condition/nested.catalog.json +37 -0
  129. data/test/command/suite/search/condition/nested.expected +7 -0
  130. data/test/command/suite/search/condition/nested.test +103 -2
  131. data/test/command/suite/search/condition/query.catalog.json +37 -0
  132. data/test/command/suite/search/condition/query.expected +7 -0
  133. data/test/command/suite/search/condition/query.test +103 -2
  134. data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +1 -1
  135. data/test/command/suite/search/condition/query/nonexistent_column.test +2 -2
  136. data/test/command/suite/search/condition/query/syntax_error.catalog.json +1 -1
  137. data/test/command/suite/search/condition/query/syntax_error.test +2 -2
  138. data/test/command/suite/search/condition/script.catalog.json +37 -0
  139. data/test/command/suite/search/condition/script.expected +7 -0
  140. data/test/command/suite/search/condition/script.test +103 -2
  141. data/test/command/suite/search/error/cyclic-source.test +1 -1
  142. data/test/command/suite/search/error/deeply-cyclic-source.test +1 -1
  143. data/test/command/suite/search/error/missing-source-parameter.test +1 -1
  144. data/test/command/suite/search/error/no-query.test +1 -1
  145. data/test/command/suite/search/error/unknown-source.test +1 -1
  146. data/test/command/suite/search/group/count.test +1 -1
  147. data/test/command/suite/search/group/limit.test +1 -1
  148. data/test/command/suite/search/group/string.catalog.json +41 -0
  149. data/test/command/suite/search/group/string.expected +18 -18
  150. data/test/command/suite/search/group/string.test +67 -22
  151. data/test/command/suite/search/group/subrecord/with-sort.catalog.json +1 -1
  152. data/test/command/suite/search/group/subrecord/with-sort.test +5 -5
  153. data/test/command/suite/search/multiple/chained.catalog.json +37 -0
  154. data/test/command/suite/search/multiple/chained.expected +14 -0
  155. data/test/command/suite/search/multiple/chained.test +103 -2
  156. data/test/command/suite/search/multiple/parallel.expected +14 -0
  157. data/test/command/suite/search/multiple/parallel.test +1 -1
  158. data/test/command/suite/search/output/attributes/invalid.catalog.json +1 -1
  159. data/test/command/suite/search/output/attributes/invalid.test +2 -2
  160. data/test/command/suite/search/output/attributes/star.catalog.json +23 -0
  161. data/test/command/suite/search/output/attributes/star.expected +27 -0
  162. data/test/command/suite/search/output/attributes/star.test +32 -0
  163. data/test/command/suite/search/range/only-output.expected +7 -0
  164. data/test/command/suite/search/range/only-output.test +1 -1
  165. data/test/command/suite/search/range/only-sort.expected +7 -0
  166. data/test/command/suite/search/range/only-sort.test +1 -1
  167. data/test/command/suite/search/range/sort-and-output.expected +7 -0
  168. data/test/command/suite/search/range/sort-and-output.test +1 -1
  169. data/test/command/suite/search/range/too-large-output-offset.expected +8 -0
  170. data/test/command/suite/search/range/too-large-output-offset.test +1 -1
  171. data/test/command/suite/search/range/too-large-sort-offset.expected +8 -0
  172. data/test/command/suite/search/range/too-large-sort-offset.test +1 -1
  173. data/test/command/suite/search/response/elapsed_time.catalog.json +1 -1
  174. data/test/command/suite/search/response/elapsed_time.test +2 -2
  175. data/test/command/suite/search/response/records/value/time.expected +12 -0
  176. data/test/command/suite/search/response/records/value/time.test +1 -1
  177. data/test/command/suite/search/simple.expected +12 -0
  178. data/test/command/suite/search/simple.test +1 -1
  179. data/test/command/suite/search/sort/default-offset-limit.expected +7 -0
  180. data/test/command/suite/search/sort/default-offset-limit.test +1 -1
  181. data/test/command/suite/search/sort/invisible-column.expected +7 -0
  182. data/test/command/suite/search/sort/invisible-column.test +1 -1
  183. data/test/unit/catalog/test_collection_volume.rb +16 -0
  184. data/test/unit/catalog/test_dataset.rb +36 -0
  185. data/test/unit/catalog/test_single_volume.rb +9 -0
  186. data/test/unit/catalog/test_slice.rb +11 -0
  187. data/test/unit/catalog/test_version1.rb +7 -12
  188. data/test/unit/catalog/test_version2.rb +7 -0
  189. data/test/unit/catalog/test_volume_collection.rb +28 -0
  190. data/test/unit/fixtures/catalog/version1.json +10 -3
  191. data/test/unit/fixtures/catalog/version2.json +2 -2
  192. data/test/unit/plugins/groonga/select/test_adapter_output.rb +8 -14
  193. data/test/unit/plugins/groonga/test_column_create.rb +5 -5
  194. data/test/unit/plugins/groonga/test_column_remove.rb +2 -2
  195. data/test/unit/plugins/groonga/test_column_rename.rb +2 -2
  196. data/test/unit/plugins/groonga/test_delete.rb +2 -2
  197. data/test/unit/plugins/groonga/test_table_create.rb +9 -9
  198. data/test/unit/plugins/groonga/test_table_remove.rb +1 -1
  199. data/test/unit/test_catalog_generator.rb +1 -1
  200. data/test/unit/test_schema_applier.rb +2 -2
  201. data/test/unit/test_watch_schema.rb +4 -4
  202. metadata +241 -72
  203. data/lib/droonga/engine/command/droonga_engine.rb +0 -441
@@ -1,441 +0,0 @@
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 "optparse"
17
- require "socket"
18
- require "ipaddr"
19
- require "fileutils"
20
-
21
- require "droonga/engine"
22
- require "droonga/event_loop"
23
- require "droonga/fluent_message_receiver"
24
- require "droonga/plugin_loader"
25
-
26
- module Droonga
27
- class Engine
28
- module Command
29
- module DroongaEngine
30
- module Signals
31
- include ServerEngine::Daemon::Signals
32
- end
33
-
34
- class Configuration
35
- DEFAULT_HOST = Socket.gethostname
36
- DEFAULT_PORT = 10031
37
-
38
- attr_reader :host, :port, :tag, :log_file, :pid_file
39
- def initialize
40
- @host = DEFAULT_HOST
41
- @port = DEFAULT_PORT
42
- @tag = "droonga"
43
- @log_file = nil
44
- @daemon = false
45
- @pid_file = nil
46
- end
47
-
48
- def engine_name
49
- "#{@host}:#{@port}/#{@tag}"
50
- end
51
-
52
- def address_family
53
- ip_address = IPAddr.new(IPSocket.getaddress(@host))
54
- ip_address.family
55
- end
56
-
57
- def log_level
58
- ENV["DROONGA_LOG_LEVEL"] || Logger::Level.default_label
59
- end
60
-
61
- def daemon?
62
- @daemon
63
- end
64
-
65
- def to_command_line
66
- [
67
- "--host", @host,
68
- "--port", @port.to_s,
69
- "--tag", @tag,
70
- "--log-level", log_level,
71
- ]
72
- end
73
-
74
- def add_command_line_options(parser)
75
- add_connection_options(parser)
76
- add_log_options(parser)
77
- add_process_options(parser)
78
- end
79
-
80
- private
81
- def add_connection_options(parser)
82
- parser.separator("")
83
- parser.separator("Connection:")
84
- parser.on("--host=HOST",
85
- "The host name of the Droonga engine",
86
- "(#{@host})") do |host|
87
- @host = host
88
- end
89
- parser.on("--port=PORT", Integer,
90
- "The port number of the Droonga engine",
91
- "(#{@port})") do |port|
92
- @port = port
93
- end
94
- parser.on("--tag=TAG",
95
- "The tag of the Droonga engine",
96
- "(#{@tag})") do |tag|
97
- @tag = tag
98
- end
99
- end
100
-
101
- def add_log_options(parser)
102
- parser.separator("")
103
- parser.separator("Log:")
104
- levels = Logger::Level::LABELS
105
- levels_label = levels.join(",")
106
- parser.on("--log-level=LEVEL", levels,
107
- "The log level of the Droonga engine",
108
- "[#{levels_label}]",
109
- "(#{log_level})") do |level|
110
- ENV["DROONGA_LOG_LEVEL"] = level
111
- end
112
- parser.on("--log-file=FILE",
113
- "Output logs to FILE") do |file|
114
- @log_file = file
115
- end
116
- end
117
-
118
- def add_process_options(parser)
119
- parser.separator("")
120
- parser.separator("Process:")
121
- parser.on("--daemon",
122
- "Run as a daemon") do
123
- @daemon = true
124
- end
125
- parser.on("--pid-file=FILE",
126
- "Put PID to the FILE") do |file|
127
- @pid_file = file
128
- end
129
- end
130
- end
131
-
132
- class Supervisor
133
- class << self
134
- def run(command_line_arguments)
135
- new.run(command_line_arguments)
136
- end
137
- end
138
-
139
- def initialize
140
- @configuration = Configuration.new
141
- @log_output = nil
142
- end
143
-
144
- def run(command_line_arguments)
145
- parse_command_line_arguments!(command_line_arguments)
146
-
147
- @listen_socket = TCPServer.new(@configuration.host,
148
- @configuration.port)
149
- @heartbeat_socket = UDPSocket.new(@configuration.address_family)
150
- @heartbeat_socket.bind(@configuration.host,
151
- @configuration.port)
152
-
153
- if @configuration.daemon?
154
- ENV["DROONGA_CATALOG"] ||= "catalog.json"
155
- ENV["DROONGA_CATALOG"] = File.expand_path(ENV["DROONGA_CATALOG"])
156
- Process.daemon
157
- end
158
-
159
- open_log_file do
160
- write_pid_file do
161
- run_main_loop
162
- end
163
- end
164
- end
165
-
166
- private
167
- def parse_command_line_arguments!(command_line_arguments)
168
- parser = OptionParser.new
169
- @configuration.add_command_line_options(parser)
170
- parser.parse!(command_line_arguments)
171
- end
172
-
173
- def run_service(ready_notify_fd=nil)
174
- listen_fd = @listen_socket.fileno
175
- heartbeat_fd = @heartbeat_socket.fileno
176
- env = {}
177
- command_line = [
178
- RbConfig.ruby,
179
- "-S",
180
- "#{$0}-service",
181
- "--listen-fd", listen_fd.to_s,
182
- "--heartbeat-fd", heartbeat_fd.to_s,
183
- *@configuration.to_command_line
184
- ]
185
- options = {
186
- listen_fd => listen_fd,
187
- heartbeat_fd => heartbeat_fd,
188
- }
189
- if ready_notify_fd
190
- command_line.push("--ready-notify-fd", ready_notify_fd.to_s)
191
- options[ready_notify_fd] = ready_notify_fd
192
- end
193
- if @log_output
194
- options[:out] = @log_output
195
- options[:err] = @log_output
196
- end
197
- spawn(env, *command_line, options)
198
- end
199
-
200
- def run_main_loop
201
- service_pid = nil
202
- running = true
203
-
204
- trap(:INT) do
205
- Process.kill(:INT, service_pid)
206
- running = false
207
- end
208
- trap(Signals::GRACEFUL_STOP) do
209
- Process.kill(Signals::GRACEFUL_STOP, service_pid)
210
- running = false
211
- end
212
- trap(Signals::IMMEDIATE_STOP) do
213
- Process.kill(Signals::IMMEDIATE_STOP, service_pid)
214
- running = false
215
- end
216
- trap(Signals::GRACEFUL_RESTART) do
217
- old_service_pid = service_pid
218
- IO.pipe do |ready_notify_read_io, ready_notify_write_io|
219
- service_pid = run_service(ready_notify_write_io.fileno)
220
- ready_notify_write_io.close
221
- IO.select([ready_notify_read_io])
222
- Process.kill(Signals::GRACEFUL_STOP, old_service_pid)
223
- end
224
- end
225
- trap(Signals::IMMEDIATE_RESTART) do
226
- old_service_pid = service_pid
227
- service_pid = run_service
228
- Process.kill(Signals::IMMEDIATE_STOP, old_service_pid)
229
- end
230
-
231
- succeeded = true
232
- while running
233
- service_pid ||= run_service
234
- finished_pid, status = Process.waitpid2(service_pid)
235
- service_pid = nil if service_pid == finished_pid
236
- if status.nil?
237
- succeeded = false
238
- break
239
- end
240
- unless status.success?
241
- succeeded = false
242
- break
243
- end
244
- end
245
-
246
- succeeded
247
- end
248
-
249
- def open_log_file
250
- if @configuration.log_file
251
- File.open(@configuration.log_file, "a") do |file|
252
- @log_output = file
253
- yield
254
- end
255
- else
256
- yield
257
- end
258
- end
259
-
260
- def write_pid_file
261
- if @configuration.pid_file
262
- File.open(@configuration.pid_file, "w") do |file|
263
- file.puts(Process.pid)
264
- end
265
- begin
266
- yield
267
- ensure
268
- FileUtils.rm_f(@configuration.pid_file)
269
- end
270
- else
271
- yield
272
- end
273
- end
274
- end
275
-
276
- class Service
277
- class << self
278
- def run(command_line_arguments)
279
- new.run(command_line_arguments)
280
- end
281
- end
282
-
283
- def initialize
284
- @configuration = Configuration.new
285
- @listen_fd = nil
286
- @heartbeat_fd = nil
287
- @ready_notiofy_fd = nil
288
- end
289
-
290
- def run(command_line_arguments)
291
- parse_command_line_arguments!(command_line_arguments)
292
- PluginLoader.load_all
293
-
294
- begin
295
- run_services
296
- ensure
297
- shutdown_services
298
- end
299
-
300
- true
301
- end
302
-
303
- private
304
- def parse_command_line_arguments!(command_line_arguments)
305
- parser = OptionParser.new
306
- @configuration.add_command_line_options(parser)
307
- add_internal_options(parser)
308
- parser.parse!(command_line_arguments)
309
- end
310
-
311
- def add_internal_options(parser)
312
- parser.separator("")
313
- parser.separator("Internal:")
314
- parser.on("--listen-fd=FD", Integer,
315
- "Use FD as the listen file descriptor") do |fd|
316
- @listen_fd = fd
317
- end
318
- parser.on("--heartbeat-fd=FD", Integer,
319
- "Use FD as the heartbeat file descriptor") do |fd|
320
- @heartbeat_fd = fd
321
- end
322
- parser.on("--ready-notify-fd=FD", Integer,
323
- "Use FD for notifying the service ready") do |fd|
324
- @ready_notify_fd = fd
325
- end
326
- end
327
-
328
- def run_services
329
- @engine = nil
330
- @receiver = nil
331
- raw_loop = Coolio::Loop.default
332
- @loop = EventLoop.new(raw_loop)
333
-
334
- run_engine
335
- run_receiver
336
- setup_signals
337
- notify_ready
338
- @loop.run
339
- end
340
-
341
- def shutdown_services
342
- shutdown_receiver
343
- shutdown_engine
344
- @loop = nil
345
- end
346
-
347
- def run_engine
348
- @engine = Engine.new(@loop, @configuration.engine_name)
349
- @engine.start
350
- end
351
-
352
- def shutdown_engine
353
- return if @engine.nil?
354
- @engine.shutdown
355
- @engine = nil
356
- end
357
-
358
- def run_receiver
359
- @receiver = create_receiver
360
- @receiver.start
361
- end
362
-
363
- def shutdown_receiver
364
- return if @receiver.nil?
365
- @receiver.shutdown
366
- @receiver = nil
367
- end
368
-
369
- def create_receiver
370
- options = {
371
- :host => @host,
372
- :port => @port,
373
- :listen_fd => @listen_fd,
374
- :heartbeat_fd => @heartbeat_fd,
375
- }
376
- FluentMessageReceiver.new(@loop, options) do |tag, time, record|
377
- on_message(tag, time, record)
378
- end
379
- end
380
-
381
- def on_message(tag, time, record)
382
- prefix, type, *arguments = tag.split(/\./)
383
- if type.nil? or type.empty? or type == "message"
384
- message = record
385
- else
386
- message = {
387
- "type" => type,
388
- "arguments" => arguments,
389
- "body" => record
390
- }
391
- end
392
- reply_to = message["replyTo"]
393
- if reply_to.is_a? String
394
- message["replyTo"] = {
395
- "type" => "#{message["type"]}.result",
396
- "to" => reply_to
397
- }
398
- end
399
-
400
- @engine.process(message)
401
- end
402
-
403
- def setup_signals
404
- trap(Signals::GRACEFUL_STOP) do
405
- stop_graceful
406
- end
407
- trap(Signals::IMMEDIATE_STOP) do
408
- stop_immediate
409
- end
410
- trap(:INT) do
411
- stop_immediate
412
- trap(:INT, "DEFAULT")
413
- end
414
- end
415
-
416
- def stop_graceful
417
- @loop.stop if @loop
418
- end
419
-
420
- def stop_immediate
421
- stop_graceful
422
- shutdown_services
423
- end
424
-
425
- def notify_ready
426
- return if @ready_notify_fd.nil?
427
- ready_notify_io = IO.new(@ready_notify_fd)
428
- @ready_notify_fd = nil
429
- watcher = Coolio::IOWatcher.new(ready_notify_io, "w")
430
- @loop.attach(watcher)
431
- watcher.on_writable do
432
- ready_notify_io.write("ready\n")
433
- ready_notify_io.close
434
- detach
435
- end
436
- end
437
- end
438
- end
439
- end
440
- end
441
- end