parallel_minion 1.2.1 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ec80ef2321aa78ba6f8b6dc7b16452f1ccb15a9b
4
- data.tar.gz: f3a394698da183ce6e64c8137ac7cf50cae98943
2
+ SHA256:
3
+ metadata.gz: 9ca9bfc8f399bcbb7cf2d90c3bb71c30fb160b23890c53ca4ca7add4a5b12fdb
4
+ data.tar.gz: a196538e92034bce7281060fcc6f22db09d3c26c49c5b6175f2471d2015aea7b
5
5
  SHA512:
6
- metadata.gz: 946b4306251796613bf5a44b89d32016aa0a9133048caaaa698206151aeb5e9dc4684e377230d767b2fb8bcc2f952a83c18c140f96bcb7e5c44fdee10f88c16c
7
- data.tar.gz: 1f52084ea14e186ff3796f8276fbc879bb99ada6d0b05fead4513b26a4611a471064c2ebbbc0cdb27ced7e1e9a41135674083436b2737108a54b921f640fb1fc
6
+ metadata.gz: 6c8f413c6fda9af1dcb94efdc4e16bf40183359f942410f38a7c57884def7ca53aee16d51c824b24c499037288ed56a5458b329bb92e87f16f8cf73c9922c15a
7
+ data.tar.gz: 44697598c5916f29a6b02bc15cf26fcd5871de81a13cc7426192d4e49ea11ed21d0fa03d9085f44daa0be0a2f565f9cf3978e3ffe84f4487910e5400870a16c6
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  parallel_minion [![Build Status](https://secure.travis-ci.org/reidmorrison/parallel_minion.png?branch=master)](http://travis-ci.org/reidmorrison/parallel_minion)
2
2
  ===============
3
3
 
4
- Pragmatic approach to parallel processing in Ruby
4
+ Wrap Ruby code with a minion so that it is run on a parallel thread.
5
5
 
6
6
  ## Description
7
7
 
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ task :gem do
9
9
  system 'gem build parallel_minion.gemspec'
10
10
  end
11
11
 
12
- task :publish => :gem do
12
+ task publish: :gem do
13
13
  system "git tag -a v#{ParallelMinion::VERSION} -m 'Tagging #{ParallelMinion::VERSION}'"
14
14
  system 'git push --tags'
15
15
  system "gem push parallel_minion-#{ParallelMinion::VERSION}.gem"
@@ -23,7 +23,7 @@ Rake::TestTask.new(:test) do |t|
23
23
  end
24
24
 
25
25
  # By default run tests against all appraisals
26
- if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
26
+ if !ENV['APPRAISAL_INITIALIZED'] && !ENV['TRAVIS']
27
27
  require 'appraisal'
28
28
  task default: :appraisal
29
29
  else
@@ -1,4 +1,3 @@
1
- require 'thread'
2
1
  require 'semantic_logger'
3
2
 
4
3
  module ParallelMinion
@@ -22,7 +22,7 @@ module ParallelMinion
22
22
  # Metrics [String]
23
23
  attr_reader :metric, :wait_metric
24
24
 
25
- attr_reader :on_timeout, :log_exception, :start_time
25
+ attr_reader :on_timeout, :log_exception, :start_time, :on_exception_level
26
26
 
27
27
  # Give an infinite amount of time to wait for a Minion to complete a task
28
28
  INFINITE = 0
@@ -40,8 +40,8 @@ module ParallelMinion
40
40
  # - Production:
41
41
  # Batch processing in Rocket Job where throughput is more important than latency.
42
42
  # http://rocketjob.io
43
- def self.enabled=(enabled)
44
- @enabled = enabled
43
+ class << self
44
+ attr_writer :enabled
45
45
  end
46
46
 
47
47
  # Returns whether minions are enabled to run in their own threads
@@ -54,8 +54,8 @@ module ParallelMinion
54
54
  #
55
55
  # Example:
56
56
  # ...
57
- def self.scoped_classes
58
- @scoped_classes
57
+ class << self
58
+ attr_reader :scoped_classes
59
59
  end
60
60
 
61
61
  def self.scoped_classes=(scoped_classes)
@@ -73,8 +73,8 @@ module ParallelMinion
73
73
  @started_log_level = level
74
74
  end
75
75
 
76
- def self.started_log_level
77
- @started_log_level
76
+ class << self
77
+ attr_reader :started_log_level
78
78
  end
79
79
 
80
80
  # Change the log level for the Completed log message.
@@ -88,8 +88,8 @@ module ParallelMinion
88
88
  @completed_log_level = level
89
89
  end
90
90
 
91
- def self.completed_log_level
92
- @completed_log_level
91
+ class << self
92
+ attr_reader :completed_log_level
93
93
  end
94
94
 
95
95
  self.started_log_level = :info
@@ -177,6 +177,10 @@ module ParallelMinion
177
177
  # Any unhandled exception raised in the block will not be logged
178
178
  # Default: :partial
179
179
  #
180
+ # :on_exception_level [:trace | :debug | :info | :warn | :error | :fatal]
181
+ # Override the log level only when an exception occurs.
182
+ # Default: ParallelMinion::Minion.completed_log_level
183
+ #
180
184
  # :enabled [Boolean]
181
185
  # Override the global setting: `ParallelMinion::Minion.enabled?` for this minion instance.
182
186
  #
@@ -193,25 +197,53 @@ module ParallelMinion
193
197
  # thread.pool.enabled=true
194
198
  #
195
199
  # Example:
196
- # ParallelMinion::Minion.new(10.days.ago, description: 'Doing something else in parallel', timeout: 1000) do |date|
200
+ # ParallelMinion::Minion.new(
201
+ # 10.days.ago,
202
+ # description: 'Doing something else in parallel',
203
+ # timeout: 1000
204
+ # ) do |date|
197
205
  # MyTable.where('created_at <= ?', date).count
198
206
  # end
199
- def initialize(*arguments, description: 'Minion', metric: nil, log_exception: nil, enabled: self.class.enabled?, timeout: INFINITE, on_timeout: nil, wait_metric: nil, &block)
207
+ #
208
+ # Example, when the result is being ignored, log full exception as an error:
209
+ # ParallelMinion::Minion.new(
210
+ # customer,
211
+ # description: "We don't care about the result",
212
+ # log_exception: :full,
213
+ # on_exception_level: :error
214
+ # ) do |customer|
215
+ # customer.save!
216
+ # end
217
+ def initialize(*arguments,
218
+ description: 'Minion',
219
+ metric: nil,
220
+ log_exception: nil,
221
+ on_exception_level: self.class.completed_log_level,
222
+ enabled: self.class.enabled?,
223
+ timeout: INFINITE,
224
+ on_timeout: nil,
225
+ wait_metric: nil,
226
+ &block)
200
227
  raise 'Missing mandatory block that Minion must perform' unless block
201
- @start_time = Time.now
202
- @exception = nil
203
- @arguments = arguments
204
- @timeout = timeout.to_f
205
- @description = description.to_s
206
- @metric = metric
207
- @log_exception = log_exception
208
- @enabled = enabled
209
- @on_timeout = on_timeout
210
-
211
- @wait_metric = (wait_metric || "#{metric}/wait") if @metric
228
+ @start_time = Time.now
229
+ @exception = nil
230
+ @arguments = arguments
231
+ @timeout = timeout.to_f
232
+ @description = description.to_s
233
+ @metric = metric
234
+ @log_exception = log_exception
235
+ @on_exception_level = on_exception_level
236
+ @enabled = enabled
237
+ @on_timeout = on_timeout
238
+
239
+ @wait_metric = (wait_metric || "#{metric}/wait") if @metric
212
240
 
213
241
  # When minion is disabled it is obvious in the logs since the name will now be 'Inline' instead of 'Minion'
214
- self.logger = SemanticLogger['Inline'] unless @enabled
242
+ unless @enabled
243
+ l = self.class.logger.dup
244
+ l.name = 'Inline'
245
+ self.logger = l
246
+ end
215
247
 
216
248
  @enabled ? run(&block) : run_inline(&block)
217
249
  end
@@ -225,7 +257,12 @@ module ParallelMinion
225
257
  # Return nil if Minion is still working and has time left to finish
226
258
  if working?
227
259
  ms = time_left
228
- logger.measure(self.class.completed_log_level, "Waited for Minion to complete: #{description}", min_duration: 0.01, metric: wait_metric) do
260
+ logger.measure(
261
+ self.class.completed_log_level,
262
+ "Waited for Minion to complete: #{description}",
263
+ min_duration: 0.01,
264
+ metric: wait_metric
265
+ ) do
229
266
  if @thread.join(ms.nil? ? nil : ms / 1000).nil?
230
267
  @thread.raise(@on_timeout.new("Minion: #{description} timed out")) if @on_timeout
231
268
  logger.warn("Timed out waiting for: #{description}")
@@ -257,7 +294,7 @@ module ParallelMinion
257
294
  # Returns 0 if no time is left
258
295
  # Returns nil if their is no time limit. I.e. :timeout was set to Minion::INFINITE (infinite time left)
259
296
  def time_left
260
- return nil if (timeout == 0) || (timeout == -1)
297
+ return nil if timeout.zero? || (timeout == -1)
261
298
  duration = timeout - (Time.now - start_time) * 1000
262
299
  duration <= 0 ? 0 : duration
263
300
  end
@@ -272,32 +309,40 @@ module ParallelMinion
272
309
  if defined?(ActiveRecord)
273
310
  if ActiveRecord::VERSION::MAJOR >= 4
274
311
  def self.current_scopes
275
- scoped_classes.collect { |klass| klass.all }
312
+ scoped_classes.collect(&:all)
276
313
  end
277
314
  else
278
315
  def self.current_scopes
279
- scoped_classes.collect { |klass| klass.scoped }
316
+ scoped_classes.collect(&:scoped)
280
317
  end
281
318
  end
282
319
  end
283
320
 
284
321
  private
285
322
 
323
+ # rubocop:disable Lint/RescueException
324
+
286
325
  # Run the supplied block of code in the current thread.
287
326
  # Useful for debugging, testing, and when running in batch environments.
288
327
  def run_inline(&block)
289
- begin
290
- logger.public_send(self.class.started_log_level, "Started #{@description}")
291
- logger.measure(self.class.completed_log_level, "Completed #{@description}", log_exception: @log_exception, metric: metric) do
292
- @result = instance_exec(*arguments, &block)
293
- end
294
- rescue Exception => exc
295
- @exception = exc
296
- ensure
297
- @duration = Time.now - start_time
328
+ logger.public_send(self.class.started_log_level, "Started #{description}")
329
+ logger.measure(
330
+ self.class.completed_log_level,
331
+ "Completed #{description}",
332
+ log_exception: log_exception,
333
+ on_exception_level: on_exception_level,
334
+ metric: metric
335
+ ) do
336
+ @result = instance_exec(*arguments, &block)
298
337
  end
338
+ rescue Exception => exc
339
+ @exception = exc
340
+ ensure
341
+ @duration = Time.now - start_time
299
342
  end
300
343
 
344
+ # rubocop:enable Lint/RescueException
345
+
301
346
  def run(&block)
302
347
  # Capture tags from current thread
303
348
  tags = SemanticLogger.tags
@@ -316,9 +361,17 @@ module ParallelMinion
316
361
  SemanticLogger.tagged(*tags) do
317
362
  SemanticLogger.named_tagged(named_tags) do
318
363
  logger.public_send(self.class.started_log_level, "Started #{description}")
364
+ # rubocop:disable Lint/RescueException
319
365
  begin
320
- proc = Proc.new { run_in_scope(scopes, &block) }
321
- logger.measure(self.class.completed_log_level, "Completed #{description}", log_exception: log_exception, metric: metric, &proc)
366
+ proc = proc { run_in_scope(scopes, &block) }
367
+ logger.measure(
368
+ self.class.completed_log_level,
369
+ "Completed #{description}",
370
+ log_exception: log_exception,
371
+ on_exception_level: on_exception_level,
372
+ metric: metric,
373
+ &proc
374
+ )
322
375
  rescue Exception => exc
323
376
  @exception = exc
324
377
  nil
@@ -327,6 +380,7 @@ module ParallelMinion
327
380
  # Return any database connections used by this thread back to the pool
328
381
  ActiveRecord::Base.clear_active_connections! if defined?(ActiveRecord::Base)
329
382
  end
383
+ # rubocop:enable Lint/RescueException
330
384
  end
331
385
  end
332
386
  end
@@ -338,12 +392,11 @@ module ParallelMinion
338
392
  else
339
393
  # Use the captured scope when running the block.
340
394
  # Each Class to scope requires passing a block to .scoping.
341
- proc = Proc.new { instance_exec(*@arguments, &block) }
395
+ proc = proc { instance_exec(*@arguments, &block) }
342
396
  first = scopes.shift
343
- scopes.each { |scope| proc = Proc.new { scope.scoping(&proc) } }
397
+ scopes.each { |scope| proc = proc { scope.scoping(&proc) } }
344
398
  @result = first.scoping(&proc)
345
399
  end
346
400
  end
347
-
348
401
  end
349
402
  end
@@ -26,6 +26,5 @@ module ParallelMinion #:nodoc:
26
26
  # end
27
27
  # end
28
28
  config.parallel_minion = ::ParallelMinion::Minion
29
-
30
29
  end
31
30
  end
@@ -1,3 +1,3 @@
1
- module ParallelMinion #:nodoc
2
- VERSION = '1.2.1'
1
+ module ParallelMinion
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -3,11 +3,11 @@ require 'erb'
3
3
  require 'active_record'
4
4
 
5
5
  ActiveRecord::Base.logger = SemanticLogger[ActiveRecord]
6
- ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read('test/config/database.yml')).result)
6
+ ActiveRecord::Base.configurations = YAML.safe_load(ERB.new(IO.read('test/config/database.yml')).result)
7
7
  ActiveRecord::Base.establish_connection(:test)
8
8
 
9
- ActiveRecord::Schema.define :version => 0 do
10
- create_table :people, :force => true do |t|
9
+ ActiveRecord::Schema.define version: 0 do
10
+ create_table :people, force: true do |t|
11
11
  t.string :name
12
12
  t.string :state
13
13
  t.string :zip_code
@@ -22,12 +22,12 @@ class MinionScopeTest < Minitest::Test
22
22
  [false, true].each do |enabled|
23
23
  describe ".new with enabled: #{enabled.inspect}" do
24
24
  before do
25
- Person.create(name: 'Jack', state: 'FL', zip_code: 38729)
26
- Person.create(name: 'John', state: 'FL', zip_code: 35363)
27
- Person.create(name: 'Jill', state: 'FL', zip_code: 73534)
28
- Person.create(name: 'Joe', state: 'NY', zip_code: 45325)
29
- Person.create(name: 'Jane', state: 'NY', zip_code: 45325)
30
- Person.create(name: 'James', state: 'CA', zip_code: 123123)
25
+ Person.create(name: 'Jack', state: 'FL', zip_code: 38_729)
26
+ Person.create(name: 'John', state: 'FL', zip_code: 35_363)
27
+ Person.create(name: 'Jill', state: 'FL', zip_code: 73_534)
28
+ Person.create(name: 'Joe', state: 'NY', zip_code: 45_325)
29
+ Person.create(name: 'Jane', state: 'NY', zip_code: 45_325)
30
+ Person.create(name: 'James', state: 'CA', zip_code: 123_123)
31
31
  # Instruct Minions to adhere to any dynamic scopes for Person model
32
32
  ParallelMinion::Minion.scoped_classes << Person
33
33
  ParallelMinion::Minion.enabled = enabled
@@ -52,7 +52,6 @@ class MinionScopeTest < Minitest::Test
52
52
  assert_equal 3, minion.result
53
53
  end
54
54
  end
55
-
56
55
  end
57
56
  end
58
57
  end
@@ -6,12 +6,35 @@ class MinionTest < Minitest::Test
6
6
  include SemanticLogger::Loggable
7
7
 
8
8
  describe ParallelMinion::Minion do
9
+ class InMemoryAppender < SemanticLogger::Subscriber
10
+ attr_reader :messages
11
+
12
+ def initialize
13
+ @messages = []
14
+ self.name = 'Minion'
15
+ end
16
+
17
+ def log(log)
18
+ messages << log.dup
19
+ end
20
+ end
21
+
22
+ let :log_messages do
23
+ appender.messages
24
+ end
25
+
26
+ let :appender do
27
+ InMemoryAppender.new
28
+ end
29
+
30
+ before do
31
+ ParallelMinion::Minion.logger = appender
32
+ end
9
33
 
10
34
  [false, true].each do |enabled|
11
35
  describe enabled ? 'enabled' : 'disabled' do
12
36
  before do
13
37
  ParallelMinion::Minion.enabled = enabled
14
- $log_structs.clear
15
38
  end
16
39
 
17
40
  it 'without parameters' do
@@ -33,7 +56,7 @@ class MinionTest < Minitest::Test
33
56
  end
34
57
 
35
58
  it 'raise exception' do
36
- minion = ParallelMinion::Minion.new(description: 'Test') { raise "An exception" }
59
+ minion = ParallelMinion::Minion.new(description: 'Test') { raise 'An exception' }
37
60
  assert_raises RuntimeError do
38
61
  minion.result
39
62
  end
@@ -45,7 +68,7 @@ class MinionTest < Minitest::Test
45
68
  assert_equal name, minion.logger.name
46
69
  end
47
70
 
48
- # TODO Blocks still have access to their original scope if variables cannot be
71
+ # TODO: Blocks still have access to their original scope if variables cannot be
49
72
  # resolved first by the parameters, then by the values in Minion itself
50
73
  # it 'not have access to local variables' do
51
74
  # name = 'Jack'
@@ -73,7 +96,7 @@ class MinionTest < Minitest::Test
73
96
  SemanticLogger.tagged('TAG') do
74
97
  assert_equal 'TAG', SemanticLogger.tags.last
75
98
  minion = ParallelMinion::Minion.new(description: 'Tag Test') do
76
- logger.info "Tag Test"
99
+ logger.info 'Tag Test'
77
100
  logger.tags.last
78
101
  end
79
102
  end
@@ -85,7 +108,7 @@ class MinionTest < Minitest::Test
85
108
  SemanticLogger.named_tagged(tag: 'TAG') do
86
109
  assert_equal({tag: 'TAG'}, SemanticLogger.named_tags)
87
110
  minion = ParallelMinion::Minion.new(description: 'Named Tags Test') do
88
- logger.info "Named Tags Test"
111
+ logger.info 'Named Tags Test'
89
112
  SemanticLogger.named_tags
90
113
  end
91
114
  end
@@ -99,7 +122,7 @@ class MinionTest < Minitest::Test
99
122
  assert_equal({tag: 'TAG'}, SemanticLogger.named_tags)
100
123
  assert_equal 'TAG', SemanticLogger.tags.last
101
124
  minion = ParallelMinion::Minion.new(description: 'Tags Test') do
102
- logger.info "Tags Test"
125
+ logger.info 'Tags Test'
103
126
  [SemanticLogger.named_tags, SemanticLogger.tags.last]
104
127
  end
105
128
 
@@ -107,7 +130,6 @@ class MinionTest < Minitest::Test
107
130
  assert_equal 'TAG', minion.result.last
108
131
  end
109
132
  end
110
-
111
133
  end
112
134
 
113
135
  it 'include metric' do
@@ -123,23 +145,41 @@ class MinionTest < Minitest::Test
123
145
  assert_equal 456, minion.result
124
146
  assert_equal 123, hash[:value]
125
147
  assert_equal 321, value
126
- SemanticLogger.flush
127
- assert log = $log_structs.first, -> { $log_structs.ai }
148
+
149
+ assert log_messages.shift, -> { log_messages.ai }
150
+ assert completed_log = log_messages.shift, -> { log_messages.ai }
151
+ # Completed log message
152
+ assert_equal metric_name, completed_log.metric, -> { completed_log.ai }
128
153
  if enabled
129
- # Completed log message
130
- assert_equal metric_name, log.metric, -> { $log_structs.ai }
131
154
  # Wait log message
132
- assert log = $log_structs.last, -> { $log_structs.ai }
133
- assert_equal "#{metric_name}/wait", log.metric, -> { $log_structs.ai }
134
- else
135
- # Timeout and wait has no effect when run inline
136
- assert_equal metric_name, log.metric, -> { $log_structs.ai }
155
+ assert waited_log = log_messages.shift, -> { log_messages.ai }
156
+ assert_equal "#{metric_name}/wait", waited_log.metric, -> { waited_log.ai }
137
157
  end
138
158
  end
139
159
 
160
+ it ':on_exception_level' do
161
+ minion = ParallelMinion::Minion.new(
162
+ description: 'Test',
163
+ on_exception_level: :error
164
+ ) do |_h|
165
+ raise 'Oh No'
166
+ end
167
+ # Wait for thread to complete
168
+ assert_raises RuntimeError do
169
+ minion.result
170
+ end
171
+
172
+ assert log_messages.shift, -> { log_messages.ai }
173
+ assert completed_log = log_messages.shift, -> { log_messages.ai }
174
+
175
+ assert_equal :error, completed_log.level
176
+ assert_equal 'Completed Test -- Exception: RuntimeError: Oh No', completed_log.message
177
+ refute completed_log.backtrace.empty?
178
+ end
179
+
140
180
  it 'handle multiple minions concurrently' do
141
181
  # Start 10 minions
142
- minions = 10.times.collect do |i|
182
+ minions = Array.new(10) do |i|
143
183
  # Each Minion returns its index in the collection
144
184
  ParallelMinion::Minion.new(i, description: "Minion:#{i}") { |counter| counter }
145
185
  end
@@ -193,15 +233,13 @@ class MinionTest < Minitest::Test
193
233
  end
194
234
 
195
235
  it 'keep the original arguments' do
196
- minion = ParallelMinion::Minion.new(1, 'data', 14.1, description: 'Test') do |num, str, float|
236
+ minion = ParallelMinion::Minion.new(1, 'data', 14.1, description: 'Test') do |num, _str, float|
197
237
  num + float
198
238
  end
199
239
  assert_equal 15.1, minion.result
200
240
  assert_equal [1, 'data', 14.1], minion.arguments
201
241
  end
202
242
  end
203
-
204
243
  end
205
-
206
244
  end
207
245
  end
Binary file
@@ -1,4 +1,4 @@
1
- #$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
1
+ # $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
2
 
3
3
  require 'minitest/autorun'
4
4
  require 'parallel_minion'
@@ -6,9 +6,3 @@ require 'semantic_logger'
6
6
 
7
7
  SemanticLogger.default_level = :trace
8
8
  SemanticLogger.add_appender(file_name: 'test.log', formatter: :color)
9
-
10
- # Setup global callback for metric so that it can be tested below
11
- $log_structs = []
12
- SemanticLogger.on_metric do |log_struct|
13
- $log_structs << log_struct.dup
14
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallel_minion
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-10 00:00:00.000000000 Z
11
+ date: 2018-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic_logger
@@ -24,8 +24,7 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.0'
27
- description: Parallel Minion allows you to take existing blocks of code and wrap them
28
- in a minion so that they can run asynchronously in a separate thread
27
+ description:
29
28
  email:
30
29
  - reidmo@gmail.com
31
30
  executables: []
@@ -56,7 +55,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
56
55
  requirements:
57
56
  - - ">="
58
57
  - !ruby/object:Gem::Version
59
- version: '2.1'
58
+ version: '2.3'
60
59
  required_rubygems_version: !ruby/object:Gem::Requirement
61
60
  requirements:
62
61
  - - ">="
@@ -64,13 +63,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
63
  version: '0'
65
64
  requirements: []
66
65
  rubyforge_project:
67
- rubygems_version: 2.6.11
66
+ rubygems_version: 2.7.3
68
67
  signing_key:
69
68
  specification_version: 4
70
- summary: Pragmatic approach to parallel and asynchronous processing in Ruby
69
+ summary: Wrap Ruby code with a minion so that it is run on a parallel thread
71
70
  test_files:
72
- - test/config/database.yml
73
- - test/minion_scope_test.rb
74
71
  - test/minion_test.rb
72
+ - test/minion_scope_test.rb
73
+ - test/config/database.yml
75
74
  - test/test_db.sqlite3
76
75
  - test/test_helper.rb