droonga-engine 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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