parallel_minion 1.2.1 → 1.3.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
- 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