droonga-engine 1.0.9 → 1.1.0

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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/benchmark/timer-watcher/benchmark.rb +44 -0
  4. data/bin/droonga-engine-absorb-data +246 -187
  5. data/bin/droonga-engine-catalog-generate +12 -12
  6. data/bin/droonga-engine-catalog-modify +4 -4
  7. data/bin/droonga-engine-join +352 -171
  8. data/bin/droonga-engine-set-role +54 -0
  9. data/bin/droonga-engine-unjoin +107 -112
  10. data/droonga-engine.gemspec +3 -3
  11. data/install.sh +55 -36
  12. data/install/centos/functions.sh +2 -2
  13. data/install/debian/functions.sh +2 -2
  14. data/lib/droonga/address.rb +26 -24
  15. data/lib/droonga/buffered_tcp_socket.rb +65 -10
  16. data/lib/droonga/catalog/base.rb +9 -6
  17. data/lib/droonga/catalog/dataset.rb +17 -41
  18. data/lib/droonga/catalog/fetcher.rb +64 -0
  19. data/lib/droonga/catalog/generator.rb +245 -0
  20. data/lib/droonga/catalog/loader.rb +66 -0
  21. data/lib/droonga/{catalog_modifier.rb → catalog/modifier.rb} +11 -18
  22. data/lib/droonga/catalog/replicas_volume.rb +123 -0
  23. data/lib/droonga/catalog/schema.rb +37 -37
  24. data/lib/droonga/catalog/single_volume.rb +11 -3
  25. data/lib/droonga/catalog/slice.rb +10 -6
  26. data/lib/droonga/catalog/{collection_volume.rb → slices_volume.rb} +47 -11
  27. data/lib/droonga/catalog/version1.rb +47 -19
  28. data/lib/droonga/catalog/version2.rb +11 -10
  29. data/lib/droonga/catalog/version2_validator.rb +4 -4
  30. data/lib/droonga/catalog/volume.rb +17 -5
  31. data/lib/droonga/changable.rb +25 -0
  32. data/lib/droonga/cluster.rb +237 -0
  33. data/lib/droonga/collector_runner.rb +4 -0
  34. data/lib/droonga/collectors.rb +2 -1
  35. data/lib/droonga/collectors/recursive_sum.rb +26 -0
  36. data/lib/droonga/command/droonga_engine.rb +404 -127
  37. data/lib/droonga/command/droonga_engine_service.rb +47 -11
  38. data/lib/droonga/command/droonga_engine_worker.rb +21 -1
  39. data/lib/droonga/command/remote_command_base.rb +78 -0
  40. data/lib/droonga/command/serf_event_handler.rb +29 -20
  41. data/lib/droonga/data_absorber_client.rb +222 -0
  42. data/lib/droonga/database_scanner.rb +106 -0
  43. data/lib/droonga/{live_nodes_list_loader.rb → deferrable.rb} +11 -24
  44. data/lib/droonga/differ.rb +58 -0
  45. data/lib/droonga/dispatcher.rb +155 -32
  46. data/lib/droonga/distributed_command_planner.rb +9 -11
  47. data/lib/droonga/engine.rb +83 -78
  48. data/lib/droonga/engine/version.rb +1 -1
  49. data/lib/droonga/engine_node.rb +301 -0
  50. data/lib/droonga/engine_state.rb +62 -40
  51. data/lib/droonga/farm.rb +44 -5
  52. data/lib/droonga/file_observer.rb +16 -12
  53. data/lib/droonga/fluent_message_receiver.rb +98 -29
  54. data/lib/droonga/fluent_message_sender.rb +30 -23
  55. data/lib/droonga/forward_buffer.rb +160 -0
  56. data/lib/droonga/forwarder.rb +73 -40
  57. data/lib/droonga/handler.rb +7 -6
  58. data/lib/droonga/handler_messenger.rb +15 -6
  59. data/lib/droonga/handler_runner.rb +6 -1
  60. data/lib/droonga/internal_fluent_message_receiver.rb +28 -8
  61. data/lib/droonga/job_pusher.rb +10 -7
  62. data/lib/droonga/job_receiver.rb +6 -4
  63. data/lib/droonga/logger.rb +7 -1
  64. data/lib/droonga/node_name.rb +90 -0
  65. data/lib/droonga/node_role.rb +72 -0
  66. data/lib/droonga/path.rb +34 -9
  67. data/lib/droonga/planner.rb +73 -7
  68. data/lib/droonga/plugin/async_command.rb +154 -0
  69. data/lib/droonga/plugins/catalog.rb +1 -0
  70. data/lib/droonga/plugins/crud.rb +22 -6
  71. data/lib/droonga/plugins/dump.rb +66 -135
  72. data/lib/droonga/plugins/groonga/delete.rb +13 -0
  73. data/lib/droonga/plugins/search/distributed_search_planner.rb +4 -4
  74. data/lib/droonga/plugins/system.rb +5 -26
  75. data/lib/droonga/plugins/system/absorb_data.rb +405 -0
  76. data/lib/droonga/plugins/system/statistics.rb +71 -0
  77. data/lib/droonga/plugins/system/status.rb +53 -0
  78. data/lib/droonga/process_control_protocol.rb +3 -1
  79. data/lib/droonga/process_supervisor.rb +32 -15
  80. data/lib/droonga/reducer.rb +69 -0
  81. data/lib/droonga/safe_file_writer.rb +1 -1
  82. data/lib/droonga/serf.rb +207 -276
  83. data/lib/droonga/serf/agent.rb +228 -0
  84. data/lib/droonga/serf/command.rb +94 -0
  85. data/lib/droonga/serf/downloader.rb +120 -0
  86. data/lib/droonga/serf/remote_command.rb +348 -0
  87. data/lib/droonga/serf/tag.rb +56 -0
  88. data/lib/droonga/service_installation.rb +2 -2
  89. data/lib/droonga/session.rb +49 -1
  90. data/lib/droonga/single_step.rb +6 -11
  91. data/lib/droonga/single_step_definition.rb +32 -1
  92. data/lib/droonga/slice.rb +14 -9
  93. data/lib/droonga/supervisor.rb +27 -20
  94. data/lib/droonga/test/stub_handler_messenger.rb +2 -1
  95. data/lib/droonga/timestamp.rb +69 -0
  96. data/lib/droonga/worker_process_agent.rb +33 -15
  97. data/sample/cluster-state.json +8 -0
  98. data/sample/cluster/Rakefile +30 -6
  99. data/test/command/fixture/integer-key-table.jsons +11 -0
  100. data/test/command/fixture/string-key-table.jsons +11 -0
  101. data/test/command/run-test.rb +4 -0
  102. data/test/command/suite/add/error/invalid-integer.expected +3 -3
  103. data/test/command/suite/add/error/invalid-time.expected +3 -3
  104. data/test/command/suite/add/{minimum.expected → key-integer.expected} +0 -0
  105. data/test/command/suite/add/{minimum.test → key-integer.test} +0 -0
  106. data/test/command/suite/add/key-string.expected +6 -0
  107. data/test/command/suite/add/key-string.test +9 -0
  108. data/test/command/suite/add/mismatched-key-type/acceptable/integer-for-string.expected +6 -0
  109. data/test/command/suite/add/mismatched-key-type/acceptable/integer-for-string.test +9 -0
  110. data/test/command/suite/add/mismatched-key-type/acceptable/string-for-integer.expected +6 -0
  111. data/test/command/suite/add/mismatched-key-type/acceptable/string-for-integer.test +9 -0
  112. data/test/command/suite/add/without-values.expected +6 -0
  113. data/test/command/suite/add/without-values.test +11 -0
  114. data/test/command/suite/dump/column/index.expected +33 -1
  115. data/test/command/suite/dump/column/index.test +1 -0
  116. data/test/command/suite/dump/column/scalar.expected +29 -1
  117. data/test/command/suite/dump/column/scalar.test +1 -0
  118. data/test/command/suite/dump/column/vector.expected +29 -1
  119. data/test/command/suite/dump/column/vector.test +1 -0
  120. data/test/command/suite/dump/record/scalar.catalog.json +12 -0
  121. data/test/command/suite/dump/record/scalar.expected +84 -0
  122. data/test/command/suite/dump/record/scalar.test +16 -0
  123. data/test/command/suite/dump/record/vector/reference.expected +83 -1
  124. data/test/command/suite/dump/record/vector/reference.test +1 -0
  125. data/test/command/suite/dump/table/array.expected +27 -1
  126. data/test/command/suite/dump/table/array.test +1 -0
  127. data/test/command/suite/dump/table/double_array_trie.expected +27 -1
  128. data/test/command/suite/dump/table/double_array_trie.test +1 -0
  129. data/test/command/suite/dump/table/hash.expected +27 -1
  130. data/test/command/suite/dump/table/hash.test +1 -0
  131. data/test/command/suite/dump/table/patricia_trie.expected +27 -1
  132. data/test/command/suite/dump/table/patricia_trie.test +1 -0
  133. data/test/command/suite/groonga/delete/{success.expected → key-integer.expected} +0 -0
  134. data/test/command/suite/groonga/delete/key-integer.test +17 -0
  135. data/test/command/suite/groonga/delete/key-string.expected +19 -0
  136. data/test/command/suite/groonga/delete/{success.test → key-string.test} +4 -6
  137. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/integer-for-string.expected +19 -0
  138. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/integer-for-string.test +17 -0
  139. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/string-for-integer.expected +19 -0
  140. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/string-for-integer.test +17 -0
  141. data/test/command/suite/message/error/missing-dataset.test +1 -0
  142. data/test/command/suite/system/absorb-data/records.catalog.json +58 -0
  143. data/test/command/suite/system/absorb-data/records.expected +32 -0
  144. data/test/command/suite/system/absorb-data/records.test +24 -0
  145. data/test/command/suite/system/statistics/object/count/empty.expected +11 -0
  146. data/test/command/suite/system/statistics/object/count/empty.test +12 -0
  147. data/test/command/suite/system/statistics/object/count/per-volume/empty.catalog.json +36 -0
  148. data/test/command/suite/system/statistics/object/count/per-volume/empty.expected +19 -0
  149. data/test/command/suite/system/statistics/object/count/per-volume/empty.test +12 -0
  150. data/test/command/suite/system/statistics/object/count/per-volume/record.catalog.json +40 -0
  151. data/test/command/suite/system/statistics/object/count/per-volume/record.expected +19 -0
  152. data/test/command/suite/system/statistics/object/count/per-volume/record.test +23 -0
  153. data/test/command/suite/system/statistics/object/count/per-volume/schema.catalog.json +40 -0
  154. data/test/command/suite/system/statistics/object/count/per-volume/schema.expected +19 -0
  155. data/test/command/suite/system/statistics/object/count/per-volume/schema.test +13 -0
  156. data/test/command/suite/system/statistics/object/count/record.catalog.json +12 -0
  157. data/test/command/suite/system/statistics/object/count/record.expected +11 -0
  158. data/test/command/suite/system/statistics/object/count/record.test +23 -0
  159. data/test/command/suite/system/statistics/object/count/schema.catalog.json +12 -0
  160. data/test/command/suite/system/statistics/object/count/schema.expected +11 -0
  161. data/test/command/suite/system/statistics/object/count/schema.test +13 -0
  162. data/test/command/suite/system/status.expected +3 -2
  163. data/test/unit/catalog/test_dataset.rb +4 -1
  164. data/test/unit/{test_catalog_generator.rb → catalog/test_generator.rb} +2 -2
  165. data/test/unit/catalog/test_replicas_volume.rb +79 -0
  166. data/test/unit/catalog/test_single_volume.rb +2 -2
  167. data/test/unit/catalog/test_slice.rb +33 -1
  168. data/test/unit/catalog/{test_collection_volume.rb → test_slices_volume.rb} +72 -11
  169. data/test/unit/catalog/test_version2.rb +3 -0
  170. data/test/unit/helper/distributed_search_planner_helper.rb +2 -2
  171. data/test/unit/plugins/catalog/test_fetch.rb +4 -4
  172. data/test/unit/plugins/crud/test_add.rb +44 -4
  173. data/test/unit/plugins/groonga/test_column_create.rb +4 -4
  174. data/test/unit/plugins/groonga/test_column_list.rb +4 -4
  175. data/test/unit/plugins/groonga/test_column_remove.rb +4 -4
  176. data/test/unit/plugins/groonga/test_column_rename.rb +4 -4
  177. data/test/unit/plugins/groonga/test_delete.rb +73 -10
  178. data/test/unit/plugins/groonga/test_table_create.rb +4 -4
  179. data/test/unit/plugins/groonga/test_table_list.rb +4 -4
  180. data/test/unit/plugins/groonga/test_table_remove.rb +4 -4
  181. data/test/unit/plugins/search/test_handler.rb +4 -4
  182. data/test/unit/plugins/search/test_planner.rb +4 -2
  183. data/test/unit/plugins/system/test_status.rb +31 -15
  184. data/test/unit/plugins/test_watch.rb +16 -16
  185. data/test/unit/test_address.rb +4 -4
  186. metadata +134 -35
  187. data/lib/droonga/catalog/volume_collection.rb +0 -79
  188. data/lib/droonga/catalog_fetcher.rb +0 -53
  189. data/lib/droonga/catalog_generator.rb +0 -243
  190. data/lib/droonga/catalog_loader.rb +0 -56
  191. data/lib/droonga/command/remote.rb +0 -404
  192. data/lib/droonga/data_absorber.rb +0 -264
  193. data/lib/droonga/node_status.rb +0 -71
  194. data/lib/droonga/serf_downloader.rb +0 -115
  195. data/test/unit/catalog/test_volume_collection.rb +0 -78
@@ -1,264 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
-
16
- require "open3"
17
-
18
- require "droonga/loggable"
19
- require "droonga/client"
20
- require "droonga/catalog_generator"
21
- require "droonga/catalog_fetcher"
22
-
23
- module Droonga
24
- class DataAbsorber
25
- include Loggable
26
-
27
- DEFAULT_MESSAGES_PER_SECOND = 100
28
-
29
- TIME_UNKNOWN = -1
30
- PROGRESS_UNKNOWN = -1
31
-
32
- class << self
33
- def absorb(params)
34
- new(params).absorb
35
- end
36
- end
37
-
38
- attr_reader :params
39
- def initialize(params)
40
- @params = params
41
-
42
- @messages_per_second = @params[:messages_per_second] || DEFAULT_MESSAGES_PER_SECOND
43
-
44
- @drndump = @params[:drndump] || "drndump"
45
- # We should use droonga-send instead of droonga-request,
46
- # because droonga-request is too slow.
47
- @client = @params[:client] || "droonga-send"
48
-
49
- @dataset = @params[:dataset] || CatalogGenerator::DEFAULT_DATASET
50
- @port = @params[:port] || CatalogGenerator::DEFAULT_PORT
51
- @tag = @params[:tag] || CatalogGenerator::DEFAULT_TAG
52
-
53
- @source_host = @params[:source_host]
54
- @destination_host = @params[:destination_host]
55
- @receiver_host = @params[:receiver_host] || @destination_host
56
-
57
- @receiver_port = @params[:receiver_port]
58
- end
59
-
60
- MESSAGES_PER_SECOND_MATCHER = /(\d+(\.\d+)?) messages\/second/
61
-
62
- def absorb
63
- drndump_command_line = [@drndump] + drndump_options
64
- client_command_line = [@client] + client_options(@client)
65
-
66
- start_time_in_seconds = Time.new.to_i
67
- env = {}
68
- Open3.pipeline_r([env, *drndump_command_line],
69
- [env, *client_command_line]) do |last_stdout, thread|
70
- last_stdout.each do |output|
71
- if block_given?
72
- messages_per_second = nil
73
- if output =~ MESSAGES_PER_SECOND_MATCHER
74
- messages_per_second = $1.to_f
75
- end
76
- yield(:progress => report_progress(start_time_in_seconds),
77
- :output => output,
78
- :messages_per_second => messages_per_second)
79
- end
80
- end
81
- end
82
- end
83
-
84
- def can_report_remaining_time?
85
- required_time_in_seconds != Droonga::DataAbsorber::TIME_UNKNOWN and
86
- required_time_in_seconds > 0
87
- end
88
-
89
- def required_time_in_seconds
90
- @required_time_in_seconds ||= calculate_required_time_in_seconds
91
- end
92
-
93
- ONE_MINUTE_IN_SECONDS = 60
94
- ONE_HOUR_IN_SECONDS = ONE_MINUTE_IN_SECONDS * 60
95
-
96
- def report_progress(start_time_in_seconds)
97
- return nil unless can_report_remaining_time?
98
-
99
- elapsed_time = Time.new.to_i - start_time_in_seconds
100
- progress = elapsed_time.to_f / required_time_in_seconds
101
- progress = [(progress * 100).to_i, 100].min
102
-
103
- remaining_seconds = [required_time_in_seconds - elapsed_time, 0].max
104
- remaining_hours = (remaining_seconds / ONE_HOUR_IN_SECONDS).floor
105
- remaining_seconds -= remaining_hours * ONE_HOUR_IN_SECONDS
106
- remaining_minutes = (remaining_seconds / ONE_MINUTE_IN_SECONDS).floor
107
- remaining_seconds -= remaining_minutes * ONE_MINUTE_IN_SECONDS
108
- remaining_time = sprintf("%02i:%02i:%02i", remaining_hours, remaining_minutes, remaining_seconds)
109
-
110
- "#{progress}% done (maybe #{remaining_time} remaining)"
111
- end
112
-
113
- def source_client
114
- options = {
115
- :host => @source_host,
116
- :port => @port,
117
- :tag => @tag,
118
- :progocol => :droonga,
119
- :receiver_host => @receiver_host,
120
- :receiver_port => 0,
121
- }
122
- @source_client ||= Droonga::Client.new(options)
123
- end
124
-
125
- def destination_client
126
- options = {
127
- :host => @destination_host,
128
- :port => @port,
129
- :tag => @tag,
130
- :progocol => :droonga,
131
- :receiver_host => @receiver_host,
132
- :receiver_port => 0,
133
- }
134
- @destination_client ||= Droonga::Client.new(options)
135
- end
136
-
137
- def source_node_suspendable?
138
- (source_replica_hosts - [@source_host]).size > 1
139
- end
140
-
141
- private
142
- def calculate_required_time_in_seconds
143
- if @client.include?("droonga-send")
144
- total_n_source_records / @messages_per_second
145
- else
146
- TIME_UNKNOWN
147
- end
148
- end
149
-
150
- def drndump_options
151
- options = []
152
- options += ["--host", @source_host] if @source_host
153
- options += ["--port", @port]
154
- options += ["--tag", @tag]
155
- options += ["--dataset", @dataset]
156
- options += ["--receiver-host", @receiver_host]
157
- options += ["--receiver-port", @receiver_port] if @receiver_port
158
- options.collect(&:to_s)
159
- end
160
-
161
- def droonga_request_options
162
- options = []
163
- options += ["--host", @destination_host]
164
- options += ["--port", @port]
165
- options += ["--tag", @tag]
166
- options += ["--receiver-host", @receiver_host]
167
- options += ["--receiver-port", @receiver_port] if @receiver_port
168
- options.collect(&:to_s)
169
- end
170
-
171
- def droonga_send_options
172
- options = []
173
-
174
- #XXX Don't use round-robin with multiple endpoints
175
- # even if there are too much data.
176
- # Schema and indexes must be sent to just one endpoint
177
- # to keep their order, but currently there is no way to
178
- # extract only schema and indexes via drndump.
179
- # So, we always use just one endpoint for now,
180
- # even if there are too much data.
181
- server = "droonga:#{params[:destination_host]}"
182
- server = "#{server}:#{params[:port].to_s}"
183
- server = "#{server}/#{params[:tag].to_s}"
184
- options += ["--server", server]
185
-
186
- #XXX We should restrict the traffic to avoid overflowing!
187
- options += ["--messages-per-second", @messages_per_second]
188
-
189
- options += ["--report-throughput"]
190
-
191
- options.collect(&:to_s)
192
- end
193
-
194
- def client_options(client)
195
- if client.include?("droonga-request")
196
- droonga_request_options
197
- elsif client.include?("droonga-send")
198
- droonga_send_options
199
- else
200
- raise ArgumentError.new("Unknwon type client: #{client}")
201
- end
202
- end
203
-
204
- def source_tables
205
- response = source_client.request("dataset" => @dataset,
206
- "type" => "table_list")
207
- body = response["body"][1]
208
- tables = body[1..-1]
209
- tables.collect do |table|
210
- table[1]
211
- end
212
- end
213
-
214
- def total_n_source_records
215
- queries = {}
216
- source_tables.each do |table|
217
- queries["n_records_of_#{table}"] = {
218
- "source" => table,
219
- "output" => {
220
- "elements" => ["count"],
221
- },
222
- }
223
- end
224
- response = source_client.request("dataset" => @dataset,
225
- "type" => "search",
226
- "body" => {
227
- "queries" => queries,
228
- })
229
- n_records = 0
230
- response["body"].each do |query_name, result|
231
- n_records += result["count"]
232
- end
233
- n_records
234
- end
235
-
236
- def source_replica_hosts
237
- @source_replica_hosts ||= get_source_replica_hosts
238
- end
239
-
240
- def get_source_replica_hosts
241
- generator = CatalogGenerator.new
242
- generator.load(source_catalog)
243
- dataset = generator.dataset_for_host(@source_host)
244
- return [] unless dataset
245
- dataset.replicas.hosts
246
- end
247
-
248
- def source_catalog
249
- @source_catalog ||= fetch_source_catalog
250
- end
251
-
252
- def fetch_source_catalog
253
- fetcher = CatalogFetcher.new(:host => @source_host,
254
- :port => @port,
255
- :tag => @tag,
256
- :receiver_host => @receiver_host)
257
- fetcher.fetch(:dataset => @dataset)
258
- end
259
-
260
- def log_tag
261
- "data-absorber"
262
- end
263
- end
264
- end
@@ -1,71 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
-
16
- require "json"
17
- require "droonga/path"
18
- require "droonga/safe_file_writer"
19
-
20
- module Droonga
21
- class NodeStatus
22
- def initialize
23
- reload
24
- end
25
-
26
- def have?(key)
27
- key = normalize_key(key)
28
- @status.include?(key)
29
- end
30
-
31
- def get(key)
32
- key = normalize_key(key)
33
- @status[key]
34
- end
35
-
36
- def set(key, value)
37
- key = normalize_key(key)
38
- @status[key] = value
39
- SafeFileWriter.write(status_file, JSON.pretty_generate(@status))
40
- end
41
-
42
- def delete(key)
43
- key = normalize_key(key)
44
- @status.delete(key)
45
- SafeFileWriter.write(status_file, JSON.pretty_generate(@status))
46
- end
47
-
48
- def reload
49
- @status = load
50
- end
51
-
52
- private
53
- def normalize_key(key)
54
- key.to_sym
55
- end
56
-
57
- def status_file
58
- @status_file ||= Path.node_status
59
- end
60
-
61
- def load
62
- if status_file.exist?
63
- contents = status_file.read
64
- unless contents.empty?
65
- return JSON.parse(contents, :symbolize_names => true)
66
- end
67
- end
68
- {}
69
- end
70
- end
71
- end
@@ -1,115 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
-
16
- require "stringio"
17
- require "tmpdir"
18
- require "fileutils"
19
-
20
- require "faraday"
21
- require "faraday_middleware"
22
- require "archive/zip"
23
-
24
- require "droonga/loggable"
25
-
26
- module Droonga
27
- class SerfDownloader
28
- include Loggable
29
-
30
- class DownloadFailed < StandardError
31
- end
32
-
33
- MAX_RETRY_COUNT = 5
34
- RETRY_INTERVAL = 10
35
-
36
- def initialize(output_path)
37
- @output_path = output_path
38
- @retry_count = 0
39
- end
40
-
41
- def download
42
- detect_platform
43
- version = "0.6.3"
44
- url_base = "https://dl.bintray.com/mitchellh/serf"
45
- base_name = "#{version}_#{@os}_#{@architecture}.zip"
46
- connection = Faraday.new(url_base) do |builder|
47
- builder.response(:follow_redirects)
48
- builder.adapter(Faraday.default_adapter)
49
- end
50
- response = connection.get(base_name)
51
- absolete_output_path = @output_path.expand_path
52
- Dir.mktmpdir do |dir|
53
- Archive::Zip.extract(StringIO.new(response.body),
54
- dir,
55
- :directories => false)
56
- FileUtils.mv("#{dir}/serf", absolete_output_path.to_s)
57
- FileUtils.chmod(0755, absolete_output_path.to_s)
58
- end
59
- rescue Archive::Zip::UnzipError => archive_error
60
- logger.warn("Downloaded zip file is broken.")
61
- if @retry_count < MAX_RETRY_COUNT
62
- @retry_count += 1
63
- sleep(RETRY_INTERVAL * @retry_count)
64
- download
65
- else
66
- raise DownloadFailed.new("Couldn't download serf executable. Try it later.")
67
- end
68
- rescue Faraday::ConnectionFailed => network_error
69
- logger.warn("Connection failed.")
70
- if @retry_count < MAX_RETRY_COUNT
71
- @retry_count += 1
72
- sleep(RETRY_INTERVAL * @retry_count)
73
- download
74
- else
75
- raise DownloadFailed.new("Couldn't download serf executable. Try it later.")
76
- end
77
- end
78
-
79
- private
80
- def detect_platform
81
- detect_os
82
- detect_architecture
83
- end
84
-
85
- def detect_os
86
- case RUBY_PLATFORM
87
- when /linux/
88
- @os = "linux"
89
- when /freebsd/
90
- @os = "freebsd"
91
- when /darwin/
92
- @os = "darwin"
93
- when /mswin|mingw/
94
- @os = "windows"
95
- else
96
- raise "Unsupported OS: #{RUBY_PLATFORM}"
97
- end
98
- end
99
-
100
- def detect_architecture
101
- case RUBY_PLATFORM
102
- when /x86_64|x64/
103
- @architecture = "amd64"
104
- when /i\d86/
105
- @architecture = "386"
106
- else
107
- raise "Unsupported architecture: #{RUBY_PLATFORM}"
108
- end
109
- end
110
-
111
- def log_tag
112
- "serf-downloader"
113
- end
114
- end
115
- end