parallel_minion 1.0.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b02090a750670c6d1b845c4c88daf19451f591c
4
- data.tar.gz: ebff60fff44c11157e93ca57fa682fd19ee226ef
3
+ metadata.gz: 540c677d0eab24f63240820396a79c81beaf12fd
4
+ data.tar.gz: 5e523e81bb240522758a1a2ef52b9ccfaa67ecab
5
5
  SHA512:
6
- metadata.gz: 57033a4c8856bd4befea01eb8af8f974b15507ab9cfabbf65a767b05cd045fbca0b1a18ca979ebda8bdf1a301d385694aa9730b0658e75a2dbfacf2d125172a5
7
- data.tar.gz: ef9594b1ae35312037a02e4dae1c3100d042964f178ea7787e46f3ef3273c5e0c1e4784ec53192c0369e321f1db22329094ddfb16fd6dfb6ac95215decfb6429
6
+ metadata.gz: b509dc355be13737e83c715479d660dfc390a0fd0fb3efc0d9f19b4c29d1c51f8009ed09f8f889d714ad1aff46a2a9735f270691cb30ba02c0004cf1c908611f
7
+ data.tar.gz: 299fb7d5ff78e5e2ebeed0db274f6481f258afc9d5b82bb2ceaeb6265c2fb68b2c41f2f2231c9627fe3d7a97b51a1650694886d51a3b5c3888b61970c3277865
data/LICENSE.txt CHANGED
@@ -186,7 +186,7 @@ Apache License
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2013, 2014 Reid Morrison
189
+ Copyright 2013, 2014, 2015 Reid Morrison
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
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 and asynchronous processing in Ruby
4
+ Pragmatic approach to parallel processing in Ruby
5
5
 
6
6
  ## Description
7
7
 
@@ -59,7 +59,7 @@ This project uses [Semantic Versioning](http://semver.org/).
59
59
 
60
60
  ## License
61
61
 
62
- Copyright 2013, 2014 Reid Morrison
62
+ Copyright 2013, 2014, 2105 Reid Morrison
63
63
 
64
64
  Licensed under the Apache License, Version 2.0 (the "License");
65
65
  you may not use this file except in compliance with the License.
@@ -15,8 +15,12 @@ module ParallelMinion
15
15
  # Returns [Array<Object>] list of arguments in the order they were passed into the initializer
16
16
  attr_reader :arguments
17
17
 
18
+ # Returns [Float] the number of milli-seconds the the minion took to complete
19
+ # Returns nil if the minion is still running
20
+ attr_reader :duration
21
+
18
22
  # Give an infinite amount of time to wait for a Minion to complete a task
19
- INFINITE = -1
23
+ INFINITE = 0
20
24
 
21
25
  # Sets whether minions are enabled to run in their own threads
22
26
  #
@@ -61,8 +65,8 @@ module ParallelMinion
61
65
  # :timeout [Integer]
62
66
  # Maximum amount of time in milli-seconds that the task may take to complete
63
67
  # before #result times out
64
- # Set to Minion::INFINITE to give the thread an infinite amount of time to complete
65
- # Default: Minion::INFINITE
68
+ # Set to 0 to give the thread an infinite amount of time to complete
69
+ # Default: 0 ( Wait forever )
66
70
  #
67
71
  # Notes:
68
72
  # - :timeout does not affect what happens to the Minion running the
@@ -77,6 +81,17 @@ module ParallelMinion
77
81
  # Not recommended in Production, but is useful for debugging purposes
78
82
  # Default: ParallelMinion::Minion.enabled?
79
83
  #
84
+ # :on_timeout [Exception]
85
+ # The class to raise on the minion when the minion times out.
86
+ # By raising the exception on the running thread it ensures that the thread
87
+ # ends due to the exception, rather than continuing to execute.
88
+ # The exception is only raised on the running minion when #result is called.
89
+ # The current call to #result will complete with a result of nil, future
90
+ # calls to #result will raise the supplied exception on the current thread
91
+ # since the thread will have terminated with that exception.
92
+ #
93
+ # Note: :on_timeout has no effect if not #enabled?
94
+ #
80
95
  # *args
81
96
  # Any number of arguments can be supplied that are passed into the block
82
97
  # in the order they are listed
@@ -115,12 +130,13 @@ module ParallelMinion
115
130
  @exception = nil
116
131
  @arguments = args.dup
117
132
  options = self.class.extract_options!(@arguments)
118
- @timeout = (options.delete(:timeout) || Minion::INFINITE).to_f
133
+ @timeout = options.delete(:timeout).to_f
119
134
  @description = (options.delete(:description) || 'Minion').to_s
120
135
  @metric = options.delete(:metric)
121
136
  @log_exception = options.delete(:log_exception)
122
137
  @enabled = options.delete(:enabled)
123
138
  @enabled = self.class.enabled? if @enabled.nil?
139
+ @on_timeout = options.delete(:on_timeout)
124
140
 
125
141
  # Warn about any unknown options.
126
142
  options.each_pair do | key, val |
@@ -138,6 +154,8 @@ module ParallelMinion
138
154
  end
139
155
  rescue Exception => exc
140
156
  @exception = exc
157
+ ensure
158
+ @duration = Time.now - @start_time
141
159
  end
142
160
  return
143
161
  end
@@ -174,6 +192,7 @@ module ParallelMinion
174
192
  ensure
175
193
  # Return any database connections used by this thread back to the pool
176
194
  ActiveRecord::Base.clear_active_connections! if defined?(ActiveRecord::Base)
195
+ @duration = Time.now - @start_time
177
196
  end
178
197
  end
179
198
  end
@@ -190,6 +209,7 @@ module ParallelMinion
190
209
  ms = time_left
191
210
  logger.benchmark_info("Waited for Minion to complete: #{@description}", min_duration: 0.01) do
192
211
  if @thread.join(ms.nil? ? nil: ms / 1000).nil?
212
+ @thread.raise(@on_timeout.new("Minion: #{@description} timed out")) if @on_timeout
193
213
  logger.warn("Timed out waiting for result from Minion: #{@description}")
194
214
  return
195
215
  end
@@ -219,7 +239,7 @@ module ParallelMinion
219
239
  # Returns 0 if no time is left
220
240
  # Returns nil if their is no time limit. I.e. :timeout was set to Minion::INFINITE (infinite time left)
221
241
  def time_left
222
- return nil if @timeout == INFINITE
242
+ return nil if (@timeout == 0) || (@timeout == -1)
223
243
  duration = @timeout - (Time.now - @start_time) * 1000
224
244
  duration <= 0 ? 0 : duration
225
245
  end
@@ -1,3 +1,3 @@
1
1
  module ParallelMinion #:nodoc
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,20 +1,14 @@
1
- # Allow test to be run in-place without requiring a gem install
2
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
-
4
- require 'semantic_logger'
5
- # Register an appender if one is not already registered
6
- SemanticLogger.default_level = :trace
7
- SemanticLogger.add_appender('test.log', &SemanticLogger::Appender::Base.colorized_formatter) if SemanticLogger.appenders.size == 0
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
8
2
 
9
3
  require 'rubygems'
10
4
  require 'erb'
11
- require 'test/unit'
5
+ #require 'test/unit'
12
6
  # Since we want both the AR and Mongoid extensions loaded we need to require them first
13
7
  require 'active_record'
14
8
  require 'active_record/relation'
15
9
  # Should redefines Proc#bind so must include after Rails
16
- require 'shoulda'
17
- require 'parallel_minion'
10
+ #require 'shoulda'
11
+ #require 'parallel_minion'
18
12
 
19
13
  ActiveRecord::Base.logger = SemanticLogger[ActiveRecord]
20
14
  ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read('test/config/database.yml')).result)
@@ -31,7 +25,7 @@ end
31
25
  class Person < ActiveRecord::Base
32
26
  end
33
27
 
34
- class MinionScopeTest < Test::Unit::TestCase
28
+ class MinionScopeTest < Minitest::Test
35
29
 
36
30
  context ParallelMinion::Minion do
37
31
  [false, true].each do |enabled|
data/test/minion_test.rb CHANGED
@@ -1,22 +1,8 @@
1
- # Allow test to be run in-place without requiring a gem install
2
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
-
4
- require 'test/unit'
5
- require 'shoulda'
6
- require 'parallel_minion'
7
-
8
- # Register an appender if one is not already registered
9
- SemanticLogger.default_level = :trace
10
- SemanticLogger.add_appender('test.log', &SemanticLogger::Appender::Base.colorized_formatter) if SemanticLogger.appenders.size == 0
11
-
12
- # Setup global callback for metric so that it can be tested below
13
- SemanticLogger.on_metric do |log_struct|
14
- $log_struct = log_struct.dup
15
- end
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
16
2
 
17
3
  # Test ParallelMinion standalone without Rails
18
4
  # Run this test standalone to verify it has no Rails dependencies
19
- class MinionTest < Test::Unit::TestCase
5
+ class MinionTest < Minitest::Test
20
6
  include SemanticLogger::Loggable
21
7
 
22
8
  context ParallelMinion::Minion do
@@ -48,7 +34,7 @@ class MinionTest < Test::Unit::TestCase
48
34
 
49
35
  should 'raise exception' do
50
36
  minion = ParallelMinion::Minion.new(description: 'Test') { raise "An exception" }
51
- assert_raise RuntimeError do
37
+ assert_raises RuntimeError do
52
38
  minion.result
53
39
  end
54
40
  end
@@ -58,7 +44,7 @@ class MinionTest < Test::Unit::TestCase
58
44
  # should 'not have access to local variables' do
59
45
  # name = 'Jack'
60
46
  # minion = ParallelMinion::Minion.new(description: 'Test') { puts name }
61
- # assert_raise NameError do
47
+ # assert_raises NameError do
62
48
  # minion.result
63
49
  # end
64
50
  # end
@@ -118,12 +104,25 @@ class MinionTest < Test::Unit::TestCase
118
104
 
119
105
  should 'timeout' do
120
106
  minion = ParallelMinion::Minion.new(description: 'Test', timeout: 100) { sleep 1 }
121
- # Only Parallel Minions time-out when they exceed the timeout
122
107
  if enabled
123
108
  assert_equal nil, minion.result
124
109
  end
125
110
  end
126
111
 
112
+ should 'timeout and terminate thread with Exception' do
113
+ minion = ParallelMinion::Minion.new(description: 'Test', timeout: 100, on_timeout: Timeout::Error) { sleep 1 }
114
+ if enabled
115
+ assert_equal nil, minion.result
116
+ # Give time for thread to terminate
117
+ sleep 0.1
118
+ assert_equal Timeout::Error, minion.exception.class
119
+ assert_equal false, minion.working?
120
+ assert_equal true, minion.completed?
121
+ assert_equal true, minion.failed?
122
+ assert_equal 0, minion.time_left
123
+ end
124
+ end
125
+
127
126
  should 'make description instance variable available' do
128
127
  minion = ParallelMinion::Minion.new(description: 'Test') do
129
128
  description
data/test/test_db.sqlite3 CHANGED
Binary file
@@ -0,0 +1,19 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'minitest/autorun'
4
+ require 'minitest/reporters'
5
+ require 'minitest/stub_any_instance'
6
+ require 'shoulda/context'
7
+ require 'parallel_minion'
8
+ require 'semantic_logger'
9
+
10
+ Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
11
+
12
+ # Register an appender if one is not already registered
13
+ SemanticLogger.default_level = :trace
14
+ SemanticLogger.add_appender('test.log', &SemanticLogger::Appender::Base.colorized_formatter) if SemanticLogger.appenders.size == 0
15
+
16
+ # Setup global callback for metric so that it can be tested below
17
+ SemanticLogger.on_metric do |log_struct|
18
+ $log_struct = log_struct.dup
19
+ 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.0.0
4
+ version: 1.1.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: 2014-11-03 00:00:00.000000000 Z
11
+ date: 2015-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic_logger
@@ -43,6 +43,7 @@ files:
43
43
  - test/minion_scope_test.rb
44
44
  - test/minion_test.rb
45
45
  - test/test_db.sqlite3
46
+ - test/test_helper.rb
46
47
  homepage: https://github.com/reidmorrison/parallel_minion
47
48
  licenses:
48
49
  - Apache License V2.0
@@ -63,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
64
  version: '0'
64
65
  requirements: []
65
66
  rubyforge_project:
66
- rubygems_version: 2.2.2
67
+ rubygems_version: 2.4.5
67
68
  signing_key:
68
69
  specification_version: 4
69
70
  summary: Pragmatic approach to parallel and asynchronous processing in Ruby
@@ -72,3 +73,4 @@ test_files:
72
73
  - test/minion_scope_test.rb
73
74
  - test/minion_test.rb
74
75
  - test/test_db.sqlite3
76
+ - test/test_helper.rb