tax_generator 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 18cb322618a66792931dece02a7ee66078c56f3d
4
- data.tar.gz: f94a7f55687d90e2a40bb7fd3527afffa035bb4a
3
+ metadata.gz: c747d61bb720bf5072dc9e9ec0870d11974e31c3
4
+ data.tar.gz: 971979df05fb6b2d3632f24b93c62ed318745ad4
5
5
  SHA512:
6
- metadata.gz: 26f93898da8b74174afd41bffd5308c7f9446766cce6166eb6c89001bf3fbb34f8620fd78ee14293cc5c64d6e8cc5d1ec4ae08f3348756c9075e5240436c20e5
7
- data.tar.gz: 05e310ba1f4dec94e32be4923197dd7eb36d9f9fcc85a3779daa68eb5a150cf1a9b45429116e255d343674aaa20e829e98cd991e419e2a1faf6bf209af395cce
6
+ metadata.gz: d0463ac2a1ce210da8b8e5ae4ea3348695c3d50e3e4a2bd526c7a05d8abe161cbdb26e02cd9bdceea1e7eed70928d563b5558bfa26d886899ce97be379916dc8
7
+ data.tar.gz: 94489169e099c7bf427d3693571c31ee7e508f680f1a078e8ef73c903f7fba861e82feae9f9db37341199ac80de6e440c9cfb16d26b18e11b983c3cb5014f49f
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ sudo: false
2
+ cache: bundler
3
+ language: ruby
4
+ before_install:
5
+ - "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
6
+ - gem install bundler
7
+ rvm:
8
+ - 2.0.0
9
+ - 2.1.5
10
+ - 2.2.2
11
+ - 2.2.3
12
+ env:
13
+ - RAILS_ENV=test RACK_ENV=test
14
+ notifications:
15
+ email: false
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  tax_generator
2
2
  =============
3
3
 
4
- [![Gem Version](https://badge.fury.io/rb/tax_generator.svg)](http://badge.fury.io/rb/tax_generator) [![Gem Downloads](https://ruby-gem-downloads-badge.herokuapp.com/tax_generator?type=total)](https://github.com/bogdanRada/tax_generator)
4
+ [![Gem Version](https://badge.fury.io/rb/tax_generator.svg)](http://badge.fury.io/rb/tax_generator) [![Gem Downloads](https://ruby-gem-downloads-badge.herokuapp.com/tax_generator?type=total)](https://github.com/bogdanRada/tax_generator) [![Analytics](https://ga-beacon.appspot.com/UA-72570203-1/bogdanRada/tax_generator)](https://github.com/bogdanRada/tax_generator)
5
5
 
6
6
  Description
7
7
  -----------
@@ -10,8 +10,8 @@ require 'active_support/core_ext/module/delegation'
10
10
  require 'slop'
11
11
  require 'nokogiri'
12
12
  require 'tree'
13
- require 'celluloid/autostart'
14
- require 'celluloid/pmap'
13
+ require 'concurrent'
14
+ require 'concurrent-edge'
15
15
 
16
16
  require 'logger'
17
17
  require 'fileutils'
@@ -20,6 +20,7 @@ require 'erb'
20
20
  require 'tilt'
21
21
  require 'tilt/erb'
22
22
  require 'thread'
23
+ require 'securerandom'
23
24
 
24
25
  %w(classes helpers).each do |folder_name|
25
26
  Gem.find_files("tax_generator/#{folder_name}/**/*.rb").each { |path| require path }
@@ -1,4 +1,5 @@
1
1
  require_relative '../helpers/application_helper'
2
+ require_relative '../helpers/methodic_actor'
2
3
  module TaxGenerator
3
4
  # class used to create the files
4
5
  #
@@ -14,9 +15,9 @@ module TaxGenerator
14
15
  # @return [TaxGenerator::TaxonomyTree] the taxonomy tree holding all the nodes from the taxonomy xml document
15
16
  # @!attribute output_folder
16
17
  # @return [String] the output folder where the new files will be created
17
- class FileCreator
18
- include Celluloid
19
- include Celluloid::Logger
18
+ class FileCreator < Concurrent::Actor::RestartingContext
19
+ include Concurrent::Async
20
+ include MethodicActor
20
21
  include TaxGenerator::ApplicationHelper
21
22
 
22
23
  attr_reader :processor, :job, :job_id, :destination, :taxonomy, :output_folder
@@ -40,12 +41,13 @@ module TaxGenerator
40
41
  # @return [void]
41
42
  #
42
43
  # @api public
43
- def work(job, manager)
44
+ def initialize(*args)
45
+ job = args[0]
46
+ @processor = args[1]
44
47
  job = job.stringify_keys
45
48
  @job = job
46
- @processor = manager
47
49
  process_job(job)
48
- @processor.register_worker_for_job(job, Actor.current)
50
+ processor.register_worker_for_job(job, self)
49
51
  end
50
52
 
51
53
  # processes the job information by retrieving keys from the hash
@@ -18,14 +18,22 @@ module TaxGenerator
18
18
  # @!attribute worker_to_job
19
19
  # @return [Hash] each key from the list is the workers mailbox address, and the value is the job being handled by the worker
20
20
  class Processor
21
- include Celluloid
22
- include Celluloid::Logger
23
- include Celluloid::Notifications
21
+ include Concurrent::Async
24
22
  include TaxGenerator::ApplicationHelper
25
23
 
26
- attr_reader :options, :worker_supervisor, :workers, :taxonomy, :jobs, :job_to_worker, :worker_to_job
24
+ QUEUES = Concurrent::Map.new do |hash, queue_name| #:nodoc:
25
+ hash.compute_if_absent(queue_name) {
26
+ Concurrent::ThreadPoolExecutor.new(
27
+ min_threads: 10, # create 10 threads at startup
28
+ max_threads: 50, # create at most 50 threads
29
+ max_queue: 0, # unbounded queue of work waiting for an available thread
30
+ )
31
+ }
32
+ end
33
+
34
+ attr_reader :options, :taxonomy, :jobs, :job_to_worker, :worker_to_job
27
35
 
28
- trap_exit :worker_died
36
+ #trap_exit :worker_died
29
37
 
30
38
  # receives a list of options that are used to determine the input files and output and input folders
31
39
  #
@@ -41,11 +49,7 @@ module TaxGenerator
41
49
  #
42
50
  # @api public
43
51
  def initialize(options = {})
44
- Celluloid.boot
45
52
  @options = options.is_a?(Hash) ? options.symbolize_keys : {}
46
- @worker_supervisor = Celluloid::SupervisionGroup.run!
47
- @workers = @worker_supervisor.pool(TaxGenerator::FileCreator, as: :workers, size: 50)
48
- Actor.current.link @workers
49
53
  @jobs_mutex = Mutex.new
50
54
  @job_to_worker_mutex = Mutex.new
51
55
  @worker_to_job_mutex = Mutex.new
@@ -54,279 +58,280 @@ module TaxGenerator
54
58
  @worker_to_job = {}
55
59
  end
56
60
 
57
- # returns the input folder from the options list
58
- # otherwise the default path
59
- #
60
- # @return [String]
61
- #
62
- # @api public
63
- def input_folder
64
- @options.fetch(:input_dir, "#{root}/data/input")
65
- end
61
+ def enqueue(job_data, queue: 'default') #:nodoc:
62
+ QUEUES[queue].post(job_data) { |job|
63
+ TaxGenerator::FileCreator.spawn(name: "worker_#{job['atlas_id']}", args: [job, self])
64
+ }
65
+ end
66
66
 
67
- # returns the taxonomy filename from the option list
68
- # otherwise the default filename
69
- #
70
- # @return [String]
71
- #
72
- # @api public
73
- def taxonomy_file_name
74
- @options.fetch(:taxonomy_filename, 'taxonomy.xml')
75
- end
67
+ # otherwise the default path
68
+ #
69
+ # @return [String]
70
+ #
71
+ # @api public
72
+ # returns the input folder from the options list
73
+ def input_folder
74
+ @options.fetch(:input_dir, "#{root}/data/input")
75
+ end
76
76
 
77
- # returns the destinations filename from the option list
78
- # otherwise the default filename
79
- #
80
- # @return [String]
81
- #
82
- # @api public
83
- def destinations_file_name
84
- @options.fetch(:destinations_filename, 'destinations.xml')
85
- end
77
+ # returns the taxonomy filename from the option list
78
+ # otherwise the default filename
79
+ #
80
+ # @return [String]
81
+ #
82
+ # @api public
83
+ def taxonomy_file_name
84
+ @options.fetch(:taxonomy_filename, 'taxonomy.xml')
85
+ end
86
86
 
87
- # returns the output folder path from the option list
88
- # otherwise the default path
89
- #
90
- # @return [String]
91
- #
92
- # @api public
93
- def output_folder
94
- @options.fetch(:output_dir, "#{root}/data/output")
95
- end
87
+ # returns the destinations filename from the option list
88
+ # otherwise the default filename
89
+ #
90
+ # @return [String]
91
+ #
92
+ # @api public
93
+ def destinations_file_name
94
+ @options.fetch(:destinations_filename, 'destinations.xml')
95
+ end
96
96
 
97
- # returns the full path to the taxonomy file
98
- #
99
- # @return [String]
100
- #
101
- # @api public
102
- def taxonomy_file_path
103
- File.join(input_folder, taxonomy_file_name)
104
- end
97
+ # returns the output folder path from the option list
98
+ # otherwise the default path
99
+ #
100
+ # @return [String]
101
+ #
102
+ # @api public
103
+ def output_folder
104
+ @options.fetch(:output_dir, "#{root}/data/output")
105
+ end
105
106
 
106
- # returns the full path to the destinations file
107
- #
108
- # @return [String]
109
- #
110
- # @api public
111
- def destinations_file_path
112
- File.join(input_folder, destinations_file_name)
113
- end
107
+ # returns the full path to the taxonomy file
108
+ #
109
+ # @return [String]
110
+ #
111
+ # @api public
112
+ def taxonomy_file_path
113
+ File.join(input_folder, taxonomy_file_name)
114
+ end
114
115
 
115
- # returns the full path to the static folder
116
- #
117
- # @return [String]
118
- #
119
- # @api public
120
- def static_output_dir
121
- File.join(output_folder, 'static')
122
- end
116
+ # returns the full path to the destinations file
117
+ #
118
+ # @return [String]
119
+ #
120
+ # @api public
121
+ def destinations_file_path
122
+ File.join(input_folder, destinations_file_name)
123
+ end
123
124
 
124
- # cleans the output folder and re-creates it and the static folder
125
- #
126
- # @return [void]
127
- #
128
- # @api public
129
- def prepare_output_dirs
130
- FileUtils.rm_rf Dir["#{output_folder}/**/*"]
131
- create_directories(output_folder, static_output_dir)
132
- FileUtils.cp_r(Dir["#{File.join(root, 'templates', 'static')}/*"], static_output_dir)
133
- end
125
+ # returns the full path to the static folder
126
+ #
127
+ # @return [String]
128
+ #
129
+ # @api public
130
+ def static_output_dir
131
+ File.join(output_folder, 'static')
132
+ end
134
133
 
135
- # checks if all workers finished and returns true or false
136
- #
137
- # @return [Boolean]
138
- #
139
- # @api public
140
- def all_workers_finished?
141
- @jobs_mutex.synchronize do
142
- @jobs.all? { |_job_id, job| job['status'] == 'finished' }
134
+ # cleans the output folder and re-creates it and the static folder
135
+ #
136
+ # @return [void]
137
+ #
138
+ # @api public
139
+ def prepare_output_dirs
140
+ FileUtils.rm_rf Dir["#{output_folder}/**/*"]
141
+ create_directories(output_folder, static_output_dir)
142
+ FileUtils.cp_r(Dir["#{File.join(root, 'templates', 'static')}/*"], static_output_dir)
143
143
  end
144
- end
145
144
 
146
- # registers all the jobs so that the managers can have access to them at any time
147
- #
148
- # @param [Array] jobs the jobs that will be registered
149
- #
150
- # @return [void]
151
- #
152
- # @api public
153
- def register_jobs(*jobs)
154
- jobs.pmap do |job|
155
- job = job.stringify_keys
145
+ # checks if all workers finished and returns true or false
146
+ #
147
+ # @return [Boolean]
148
+ #
149
+ # @api public
150
+ def all_workers_finished?
156
151
  @jobs_mutex.synchronize do
157
- @jobs[job['atlas_id']] = job
152
+ @jobs.all? { |_job_id, job| job['status'] == 'finished' }
158
153
  end
159
154
  end
160
- end
161
155
 
162
- # registers all the jobs, and then delegates them to workers
163
- # @see #register_jobs
164
- # @see TaxGenerator::FileCreator#work
165
- #
166
- # @param [Array] jobs the jobs that will be delegated to the workers
167
- #
168
- # @return [void]
169
- #
170
- # @api public
171
- def delegate_job(*jobs)
172
- # jobs need to be added into the manager before starting task to avoid adding new key while iterating
173
- register_jobs(*jobs)
174
- current_actor = Actor.current
175
- @jobs_mutex.synchronize do
176
- @jobs.pmap do |_job_id, job|
177
- @workers.async.work(job, current_actor) if @workers.alive?
156
+ # registers all the jobs so that the managers can have access to them at any time
157
+ #
158
+ # @param [Array] jobs the jobs that will be registered
159
+ #
160
+ # @return [void]
161
+ #
162
+ # @api public
163
+ def register_jobs(*jobs)
164
+ jobs.each do |job|
165
+ job = job.stringify_keys
166
+ @jobs_mutex.synchronize do
167
+ @jobs[job['atlas_id']] = job
168
+ end
178
169
  end
179
170
  end
180
- end
181
171
 
182
- # parses the destinations xml document, gets each destination and adds a new job for that
183
- # destination in the job list and then returns it
184
- # @see #nokogiri_xml
185
- #
186
- # @return [Array<Hash>]
187
- #
188
- # @api public
189
- def fetch_file_jobs
190
- jobs = []
191
- count = 0
192
- @taxonomy.document.xpath('.//taxonomy').pmap do |_taxonomy_node|
193
- count += 1
194
- jobs << { atlas_id: count, taxonomy: @taxonomy, destination: nil, output_folder: output_folder }
172
+ # registers all the jobs, and then delegates them to workers
173
+ # @see #register_jobs
174
+ # @see TaxGenerator::FileCreator#work
175
+ #
176
+ # @param [Array] jobs the jobs that will be delegated to the workers
177
+ #
178
+ # @return [void]
179
+ #
180
+ # @api public
181
+ def delegate_job(*jobs)
182
+ # jobs need to be added into the manager before starting task to avoid adding new key while iterating
183
+ register_jobs(*jobs)
184
+ @jobs_mutex.synchronize do
185
+ @jobs.each do |_job_id, job|
186
+ enqueue(job)
187
+ end
188
+ end
195
189
  end
196
- nokogiri_xml(destinations_file_path).xpath('//destination').pmap do |destination|
197
- atlas_id = destination.attributes['atlas_id']
198
- jobs << { atlas_id: atlas_id.value, taxonomy: @taxonomy, destination: destination, output_folder: output_folder }
190
+
191
+ # parses the destinations xml document, gets each destination and adds a new job for that
192
+ # destination in the job list and then returns it
193
+ # @see #nokogiri_xml
194
+ #
195
+ # @return [Array<Hash>]
196
+ #
197
+ # @api public
198
+ def fetch_file_jobs
199
+ jobs = []
200
+ @taxonomy.taxonomies.each do |taxonomy_node|
201
+ jobs << { atlas_id: taxonomy_node.name, taxonomy: @taxonomy, destination: nil, output_folder: output_folder }
202
+ end
203
+ nokogiri_xml(destinations_file_path).xpath('//destination').each do |destination|
204
+ atlas_id = destination.attributes['atlas_id']
205
+ jobs << { atlas_id: atlas_id.value, taxonomy: @taxonomy, destination: destination, output_folder: output_folder }
206
+ end
207
+ jobs
199
208
  end
200
- jobs
201
- end
202
209
 
203
- # fetches the jobs for file generation, then delegates the jobs to workers and waits untill workers finish
204
- # @see #fetch_file_jobs
205
- # @see #delegate_job
206
- # @see #wait_jobs_termination
207
- #
208
- # @return [void]
209
- #
210
- # @api public
211
- def generate_files
212
- jobs = fetch_file_jobs
213
- delegate_job(*jobs)
214
- wait_jobs_termination
215
- end
210
+ # fetches the jobs for file generation, then delegates the jobs to workers and waits untill workers finish
211
+ # @see #fetch_file_jobs
212
+ # @see #delegate_job
213
+ # @see #wait_jobs_termination
214
+ #
215
+ # @return [void]
216
+ #
217
+ # @api public
218
+ def generate_files
219
+ jobs = fetch_file_jobs
220
+ delegate_job(*jobs)
221
+ wait_jobs_termination
222
+ end
216
223
 
217
- # retrieves the information about the node from the tree and generates for each destination a new File
218
- # @see #create_file
219
- #
220
- # @return [void]
221
- #
222
- # @api public
223
- def wait_jobs_termination
224
- sleep(0.1) until all_workers_finished?
225
- terminate
226
- end
224
+ # retrieves the information about the node from the tree and generates for each destination a new File
225
+ # @see #create_file
226
+ #
227
+ # @return [void]
228
+ #
229
+ # @api public
230
+ def wait_jobs_termination
231
+ sleep(0.1) until all_workers_finished?
232
+ end
227
233
 
228
- # registeres a worker inside the job_to_worker storage using the 'atlas_id' key from the job hash
229
- # @param [TaxGenerator::FileCreator] worker the worker that needs to be registered
230
- # @param [Hash] job the job that will be used to register the worker
231
- #
232
- # @return [void]
233
- #
234
- # @api public
235
- def register_job_to_worker(job, worker)
236
- @job_to_worker_mutex.synchronize do
237
- @job_to_worker[job['atlas_id']] = worker
234
+ # registeres a worker inside the job_to_worker storage using the 'atlas_id' key from the job hash
235
+ # @param [TaxGenerator::FileCreator] worker the worker that needs to be registered
236
+ # @param [Hash] job the job that will be used to register the worker
237
+ #
238
+ # @return [void]
239
+ #
240
+ # @api public
241
+ def register_job_to_worker(job, worker)
242
+ @job_to_worker_mutex.synchronize do
243
+ @job_to_worker[job['atlas_id']] = worker
244
+ end
238
245
  end
239
- end
240
246
 
241
- # registeres a job to a worker, using the mailbox address of the worker (which is unique)
242
- # @param [TaxGenerator::FileCreator] worker the worker that will be used to registerr the job
243
- # @param [Hash] job the job that willbe registered to a worker
244
- #
245
- # @return [void]
246
- #
247
- # @api public
248
- def register_worker_to_job(job, worker)
249
- @worker_to_job_mutex.synchronize do
250
- @worker_to_job[worker.mailbox.address] = job
247
+ # registeres a job to a worker, using the mailbox address of the worker (which is unique)
248
+ # @param [TaxGenerator::FileCreator] worker the worker that will be used to registerr the job
249
+ # @param [Hash] job the job that willbe registered to a worker
250
+ #
251
+ # @return [void]
252
+ #
253
+ # @api public
254
+ def register_worker_to_job(job, worker)
255
+ @worker_to_job_mutex.synchronize do
256
+ @worker_to_job[worker.name] = job
257
+ end
251
258
  end
252
- end
253
259
 
254
- # registers the worker so that the current actor has access to it at any given time and starts the worker
255
- # @see TaxGenerator::FileCreator#start_work
256
- # @see #register_job_to_worker
257
- # @see #register_worker_to_job
258
- #
259
- # @param [Hash] job the job that the worker will work
260
- # @param [TaxGenerator::FileCreator] worker the worker that will create the file
261
- #
262
- # @return [void]
263
- #
264
- # @api public
265
- def register_worker_for_job(job, worker)
266
- register_job_to_worker(job, worker)
267
- register_worker_to_job(job, worker)
268
- log_message("worker #{worker.job_id} registed into manager")
269
- Actor.current.link worker
270
- worker.async.start_work
271
- end
260
+ # registers the worker so that the current actor has access to it at any given time and starts the worker
261
+ # @see TaxGenerator::FileCreator#start_work
262
+ # @see #register_job_to_worker
263
+ # @see #register_worker_to_job
264
+ #
265
+ # @param [Hash] job the job that the worker will work
266
+ # @param [TaxGenerator::FileCreator] worker the worker that will create the file
267
+ #
268
+ # @return [void]
269
+ #
270
+ # @api public
271
+ def register_worker_for_job(job, worker)
272
+ register_job_to_worker(job, worker)
273
+ register_worker_to_job(job, worker)
274
+ log_message("worker #{worker.job_id} registed into manager")
275
+ worker.tell(:start_work)
276
+ end
272
277
 
273
- # generates the taxonomy tree , prints it and generates the files
274
- # @see TaxGenerator::TaxonomyTree#new
275
- # @see Tree::TreeNode#print_tree
276
- # @see #generate_files
277
- #
278
- # @return [void]
279
- #
280
- # @api public
281
- def work
282
- prepare_output_dirs
283
- if File.directory?(input_folder) && File.file?(taxonomy_file_path) && File.file?(destinations_file_path)
284
- @taxonomy = TaxGenerator::TaxonomyTree.new(taxonomy_file_path)
285
- @taxonomy.print_tree
286
- generate_files
287
- else
288
- log_message('Please provide valid options', log_method: 'fatal')
278
+ # generates the taxonomy tree , prints it and generates the files
279
+ # @see TaxGenerator::TaxonomyTree#new
280
+ # @see Tree::TreeNode#print_tree
281
+ # @see #generate_files
282
+ #
283
+ # @return [void]
284
+ #
285
+ # @api public
286
+ def work
287
+ prepare_output_dirs
288
+ if File.directory?(input_folder) && File.file?(taxonomy_file_path) && File.file?(destinations_file_path)
289
+ @taxonomy = TaxGenerator::TaxonomyTree.new(taxonomy_file_path)
290
+ @taxonomy.print_tree
291
+ generate_files
292
+ else
293
+ log_message('Please provide valid options', log_method: 'fatal')
294
+ end
289
295
  end
290
- end
291
296
 
292
- # fetches the job from a worker
293
- # @param [TaxGenerator::FileCreator] worker the worker that died
294
- #
295
- # @return [void]
296
- #
297
- # @api public
298
- def get_job_from_worker(worker)
299
- @worker_to_job_mutex.synchronize do
300
- @worker_to_job[worker.mailbox.address]
297
+ # fetches the job from a worker
298
+ # @param [TaxGenerator::FileCreator] worker the worker that died
299
+ #
300
+ # @return [void]
301
+ #
302
+ # @api public
303
+ def get_job_from_worker(worker)
304
+ @worker_to_job_mutex.synchronize do
305
+ @worker_to_job[worker.name]
306
+ end
301
307
  end
302
- end
303
308
 
304
- # deletes the worker from the worker_to_job storage
305
- # @param [TaxGenerator::FileCreator] worker the worker that died
306
- #
307
- # @return [void]
308
- #
309
- # @api public
310
- def delete_from_worker_to_job(worker)
311
- mailbox = worker.mailbox.address
312
- @worker_to_job_mutex.synchronize do
313
- @worker_to_job.delete(mailbox)
309
+ # deletes the worker from the worker_to_job storage
310
+ # @param [TaxGenerator::FileCreator] worker the worker that died
311
+ #
312
+ # @return [void]
313
+ #
314
+ # @api public
315
+ def delete_from_worker_to_job(worker)
316
+ name = worker.name
317
+ @worker_to_job_mutex.synchronize do
318
+ @worker_to_job.delete(name)
319
+ end
320
+ name
314
321
  end
315
- mailbox
316
- end
317
322
 
318
- # logs the message about working being dead if a worker crashes
319
- # @param [TaxGenerator::FileCreator] worker the worker that died
320
- # @param [String] reason the reason for which the worker died
321
- #
322
- # @return [void]
323
- #
324
- # @api public
325
- def worker_died(worker, reason)
326
- job = get_job_from_worker(worker)
327
- mailbox = delete_from_worker_to_job(worker)
328
- return if reason.blank? || job.blank?
329
- log_message("worker job #{job['atlas_id']} with mailbox #{mailbox.inspect} died for reason: #{log_error(reason)}", log_method: 'fatal')
323
+ # logs the message about working being dead if a worker crashes
324
+ # @param [TaxGenerator::FileCreator] worker the worker that died
325
+ # @param [String] reason the reason for which the worker died
326
+ #
327
+ # @return [void]
328
+ #
329
+ # @api public
330
+ def worker_died(worker, reason)
331
+ job = get_job_from_worker(worker)
332
+ worker_name = delete_from_worker_to_job(worker)
333
+ return if reason.blank? || job.blank?
334
+ log_message("worker job #{job['atlas_id']} with name #{worker_name.inspect} died for reason: #{log_error(reason)}", log_method: 'fatal')
335
+ end
330
336
  end
331
337
  end
332
- end
@@ -9,7 +9,7 @@ module TaxGenerator
9
9
  # @return [Nokogiri::XML] the xml document used to build the tree
10
10
  class TaxonomyTree
11
11
  include TaxGenerator::ApplicationHelper
12
- attr_reader :root_node, :document
12
+ attr_reader :root_node, :document, :taxonomies
13
13
 
14
14
  # receives a file path that will be parsed and used to build the tree
15
15
  # @see Tree::TreeNode#new
@@ -23,6 +23,7 @@ module TaxGenerator
23
23
  def initialize(file_path)
24
24
  @document = nokogiri_xml(file_path)
25
25
  @root_node = TaxGenerator::TaxonomyNode.new('ROOT', 'ROOT')
26
+ @taxonomies = []
26
27
  find_taxonomies
27
28
  end
28
29
 
@@ -35,11 +36,10 @@ module TaxGenerator
35
36
  #
36
37
  # @api public
37
38
  def find_taxonomies
38
- count = 0
39
- @document.xpath('.//taxonomy').pmap do |taxonomy_node|
40
- count += 1
39
+ @document.xpath('.//taxonomy').each do |taxonomy_node|
41
40
  taxonomy_name = taxonomy_node.at_xpath('.//taxonomy_name')
42
- tax_node = insert_node(count.to_s, taxonomy_name.content, @root_node)
41
+ tax_node = insert_node(SecureRandom.uuid, taxonomy_name.content, @root_node)
42
+ @taxonomies << tax_node
43
43
  add_node(taxonomy_node, tax_node, skip_add: true)
44
44
  end
45
45
  end
@@ -110,7 +110,7 @@ module TaxGenerator
110
110
  def add_node(taxonomy_node, node, options = {})
111
111
  tax_node = options[:skip_add].present? ? node : add_taxonomy_node(taxonomy_node, node)
112
112
  return unless taxonomy_node.children.any?
113
- taxonomy_node.xpath('./node').pmap do |child_node|
113
+ taxonomy_node.xpath('./node').each do |child_node|
114
114
  add_node(child_node, tax_node) if tax_node.present?
115
115
  end
116
116
  end
@@ -49,26 +49,12 @@ module TaxGenerator
49
49
  #
50
50
  # @api public
51
51
  def create_directories(*args)
52
- args.pmap do |argument|
52
+ args.each do |argument|
53
53
  FileUtils.mkdir_p(argument) unless File.directory?(argument)
54
54
  end
55
55
  end
56
56
 
57
- # sets the exception handler for celluloid actors
58
- #
59
- #
60
- # @return [void]
61
- #
62
- # @api public
63
- def set_celluloid_exception_handling
64
- Celluloid.logger = app_logger
65
- Celluloid.task_class = Celluloid::TaskThread
66
- Celluloid.exception_handler do |ex|
67
- unless ex.is_a?(Interrupt)
68
- log_error(ex)
69
- end
70
- end
71
- end
57
+
72
58
 
73
59
  # Reads a file and interpretes it as ERB
74
60
  #
@@ -133,7 +119,6 @@ module TaxGenerator
133
119
  #
134
120
  # @api public
135
121
  def execute_with_rescue
136
- set_celluloid_exception_handling
137
122
  yield if block_given?
138
123
  rescue Interrupt
139
124
  rescue_interrupt
@@ -0,0 +1,6 @@
1
+ module MethodicActor
2
+ def on_message(message)
3
+ method, *args = message
4
+ self.send(method, *args)
5
+ end
6
+ end
@@ -15,9 +15,9 @@ module TaxGenerator
15
15
  # major release version
16
16
  MAJOR = 0
17
17
  # minor release version
18
- MINOR = 5
18
+ MINOR = 6
19
19
  # tiny release version
20
- TINY = 2
20
+ TINY = 0
21
21
  # prelease version ( set this only if it is a prelease)
22
22
  PRE = nil
23
23
 
@@ -18,8 +18,8 @@ Gem::Specification.new do |s|
18
18
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
 
20
20
  s.add_runtime_dependency 'nokogiri', '~> 1.6', '>= 1.6.7'
21
- s.add_runtime_dependency 'celluloid', '~> 0.16', '~> 0.16.0'
22
- s.add_runtime_dependency 'celluloid-pmap', '~> 0.2', '~> 0.2.2'
21
+ s.add_runtime_dependency 'concurrent-ruby', '~> 1.0', '>= 1.0'
22
+ s.add_runtime_dependency 'concurrent-ruby-edge', '~> 0.2' , '>= 0.2'
23
23
  s.add_runtime_dependency 'slop', '~> 4.2', '>= 4.2.1'
24
24
  s.add_runtime_dependency 'activesupport', '~> 4.2', '>= 4.2.5'
25
25
  s.add_runtime_dependency 'rubytree', '~> 0.9', '>= 0.9.6'
@@ -31,8 +31,8 @@ Gem::Specification.new do |s|
31
31
  s.add_development_dependency 'simplecov-summary', '~> 0.0.4', '>= 0.0.4'
32
32
  s.add_development_dependency 'mocha', '~> 1.1', '>= 1.1'
33
33
 
34
- s.add_development_dependency 'rubocop', '~> 0.33', '>= 0.33'
35
- s.add_development_dependency 'reek', '~> 3.7', '>= 3.7'
34
+ s.add_development_dependency 'concurrent-ruby-ext', '~> 1.0' , '>= 1.0'
35
+
36
36
  s.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7'
37
37
  s.add_development_dependency 'yard-rspec', '~> 0.1', '>= 0.1'
38
38
  s.add_development_dependency 'redcarpet', '~> 3.3', '>= 3.3'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tax_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bogdanRada
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-05 00:00:00.000000000 Z
11
+ date: 2016-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -31,35 +31,35 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: 1.6.7
33
33
  - !ruby/object:Gem::Dependency
34
- name: celluloid
34
+ name: concurrent-ruby
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '0.16'
40
- - - "~>"
39
+ version: '1.0'
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 0.16.0
42
+ version: '1.0'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '0.16'
50
- - - "~>"
49
+ version: '1.0'
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 0.16.0
52
+ version: '1.0'
53
53
  - !ruby/object:Gem::Dependency
54
- name: celluloid-pmap
54
+ name: concurrent-ruby-edge
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
59
  version: '0.2'
60
- - - "~>"
60
+ - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: 0.2.2
62
+ version: '0.2'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
@@ -67,9 +67,9 @@ dependencies:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0.2'
70
- - - "~>"
70
+ - - ">="
71
71
  - !ruby/object:Gem::Version
72
- version: 0.2.2
72
+ version: '0.2'
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: slop
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -251,45 +251,25 @@ dependencies:
251
251
  - !ruby/object:Gem::Version
252
252
  version: '1.1'
253
253
  - !ruby/object:Gem::Dependency
254
- name: rubocop
255
- requirement: !ruby/object:Gem::Requirement
256
- requirements:
257
- - - "~>"
258
- - !ruby/object:Gem::Version
259
- version: '0.33'
260
- - - ">="
261
- - !ruby/object:Gem::Version
262
- version: '0.33'
263
- type: :development
264
- prerelease: false
265
- version_requirements: !ruby/object:Gem::Requirement
266
- requirements:
267
- - - "~>"
268
- - !ruby/object:Gem::Version
269
- version: '0.33'
270
- - - ">="
271
- - !ruby/object:Gem::Version
272
- version: '0.33'
273
- - !ruby/object:Gem::Dependency
274
- name: reek
254
+ name: concurrent-ruby-ext
275
255
  requirement: !ruby/object:Gem::Requirement
276
256
  requirements:
277
257
  - - "~>"
278
258
  - !ruby/object:Gem::Version
279
- version: '3.7'
259
+ version: '1.0'
280
260
  - - ">="
281
261
  - !ruby/object:Gem::Version
282
- version: '3.7'
262
+ version: '1.0'
283
263
  type: :development
284
264
  prerelease: false
285
265
  version_requirements: !ruby/object:Gem::Requirement
286
266
  requirements:
287
267
  - - "~>"
288
268
  - !ruby/object:Gem::Version
289
- version: '3.7'
269
+ version: '1.0'
290
270
  - - ">="
291
271
  - !ruby/object:Gem::Version
292
- version: '3.7'
272
+ version: '1.0'
293
273
  - !ruby/object:Gem::Dependency
294
274
  name: yard
295
275
  requirement: !ruby/object:Gem::Requirement
@@ -404,6 +384,7 @@ files:
404
384
  - ".reek"
405
385
  - ".rspec"
406
386
  - ".rubocop.yml"
387
+ - ".travis.yml"
407
388
  - Gemfile
408
389
  - LICENSE
409
390
  - README.md
@@ -424,6 +405,7 @@ files:
424
405
  - lib/tax_generator/classes/taxonomy_tree.rb
425
406
  - lib/tax_generator/cli.rb
426
407
  - lib/tax_generator/helpers/application_helper.rb
408
+ - lib/tax_generator/helpers/methodic_actor.rb
427
409
  - lib/tax_generator/version.rb
428
410
  - spec/lib/tax_generator/application_spec.rb
429
411
  - spec/lib/tax_generator/classes/destination_spec.rb
@@ -456,7 +438,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
456
438
  version: '0'
457
439
  requirements: []
458
440
  rubyforge_project:
459
- rubygems_version: 2.4.8
441
+ rubygems_version: 2.5.1
460
442
  signing_key:
461
443
  specification_version: 4
462
444
  summary: Tax generator is a simple XML processor and generator of HTMl files and generates