taskinator 0.3.0 → 0.3.1

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: 683a1ffedb432057d353d7ebbc31dff766bce83c
4
- data.tar.gz: 92c78c8a6e2c87769269147557c9c2cb13be52fa
3
+ metadata.gz: 2f06333f9729441692c47b0eecc144080b2711ff
4
+ data.tar.gz: 4b6db6e7787af743783a45dea8070813d9d2df9e
5
5
  SHA512:
6
- metadata.gz: d9449a313b53581d06109e16d6f1a268a5f786848fc4d725e0852b773dbe99b1a68898a88c0d077bfb48590b976dbc4ca821e9207f20b50343f924493c35d9aa
7
- data.tar.gz: 5c621a66e20dfef0f7800482ea5dd308c7470393537022791d3398a4f12c9350ca40a89267de82a149adcaf5c8561ae8b6aa732826ab85843e0f330cb701396f
6
+ metadata.gz: 4d352409fcbfce51f8591779c291cee6a2fcecd2513a33d07657c8e85045654af4af639908704e3e9f7fda3c72859781bf36d96c7e4dfdbb48decd3e2a38e161
7
+ data.tar.gz: c849ec329437762c590e2858c794729cf08264343907692ba564a9a7cd5858da7109452c88bb9777299a36726008feea3dfb4201706913be011ad4996c7e0621
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ v0.3.1 - 16 Sep 2015
2
+ ---
3
+ Added redis-semaphore gem, for fix to concurrent processes completion logic.
4
+
1
5
  v0.3.0 - 28 Aug 2015
2
6
  ---
3
7
  Added created_at and updated_at to process and task as attributes.
data/Gemfile.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: git://github.com/mperham/sidekiq.git
3
- revision: b0cdd4cc868e7564b78ee34965067e025ec41689
3
+ revision: 50fc8ee7c3f7c5e4049db598c0e14465a67a877c
4
4
  specs:
5
5
  sidekiq (3.5.0)
6
6
  celluloid (~> 0.17.0)
@@ -12,16 +12,17 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- taskinator (0.3.0)
15
+ taskinator (0.3.1)
16
16
  connection_pool (>= 2.2.0)
17
17
  json (>= 1.8.2)
18
18
  redis (>= 3.2.1)
19
19
  redis-namespace (>= 1.5.2)
20
+ redis-semaphore (>= 0.2.4)
20
21
 
21
22
  GEM
22
23
  remote: https://rubygems.org/
23
24
  specs:
24
- activesupport (4.2.3)
25
+ activesupport (4.2.4)
25
26
  i18n (~> 0.7)
26
27
  json (~> 1.7, >= 1.7.7)
27
28
  minitest (~> 5.1)
@@ -29,7 +30,7 @@ GEM
29
30
  tzinfo (~> 1.1)
30
31
  byebug (5.0.0)
31
32
  columnize (= 0.9.0)
32
- celluloid (0.17.1.1)
33
+ celluloid (0.17.1.2)
33
34
  bundler
34
35
  celluloid-essentials
35
36
  celluloid-extras
@@ -39,37 +40,37 @@ GEM
39
40
  dotenv
40
41
  nenv
41
42
  rspec-logsplit (>= 0.1.2)
42
- timers (~> 4.0.0)
43
- celluloid-essentials (0.20.2)
43
+ timers (>= 4.1.1)
44
+ celluloid-essentials (0.20.2.1)
44
45
  bundler
45
46
  dotenv
46
47
  nenv
47
48
  rspec-logsplit (>= 0.1.2)
48
- timers (~> 4.0.0)
49
- celluloid-extras (0.20.0)
49
+ timers (>= 4.1.1)
50
+ celluloid-extras (0.20.1)
50
51
  bundler
51
52
  dotenv
52
53
  nenv
53
54
  rspec-logsplit (>= 0.1.2)
54
- timers (~> 4.0.0)
55
- celluloid-fsm (0.20.0)
55
+ timers (>= 4.1.1)
56
+ celluloid-fsm (0.20.1)
56
57
  bundler
57
58
  dotenv
58
59
  nenv
59
60
  rspec-logsplit (>= 0.1.2)
60
- timers (~> 4.0.0)
61
- celluloid-pool (0.20.0)
61
+ timers (>= 4.1.1)
62
+ celluloid-pool (0.20.1)
62
63
  bundler
63
64
  dotenv
64
65
  nenv
65
66
  rspec-logsplit (>= 0.1.2)
66
- timers (~> 4.0.0)
67
- celluloid-supervision (0.20.1)
67
+ timers (>= 4.1.1)
68
+ celluloid-supervision (0.20.1.1)
68
69
  bundler
69
70
  dotenv
70
71
  nenv
71
72
  rspec-logsplit (>= 0.1.2)
72
- timers (~> 4.0.0)
73
+ timers (>= 4.1.1)
73
74
  coderay (1.1.0)
74
75
  columnize (0.9.0)
75
76
  connection_pool (2.2.0)
@@ -86,13 +87,13 @@ GEM
86
87
  domain_name (0.5.24)
87
88
  unf (>= 0.0.5, < 1.0.0)
88
89
  dotenv (2.0.2)
89
- hitimes (1.2.2)
90
+ hitimes (1.2.3)
90
91
  http-cookie (1.0.2)
91
92
  domain_name (~> 0.5)
92
93
  i18n (0.7.0)
93
94
  json (1.8.3)
94
95
  method_source (0.8.2)
95
- mime-types (2.6.1)
96
+ mime-types (2.6.2)
96
97
  minitest (5.8.0)
97
98
  mono_logger (1.1.0)
98
99
  multi_json (1.11.2)
@@ -112,6 +113,8 @@ GEM
112
113
  redis (3.2.1)
113
114
  redis-namespace (1.5.2)
114
115
  redis (~> 3.0, >= 3.0.4)
116
+ redis-semaphore (0.2.4)
117
+ redis
115
118
  resque (1.25.2)
116
119
  mono_logger (~> 1.0)
117
120
  multi_json (~> 1.0)
@@ -159,7 +162,7 @@ GEM
159
162
  thor (0.19.1)
160
163
  thread_safe (0.3.5)
161
164
  tilt (2.0.1)
162
- timers (4.0.1)
165
+ timers (4.1.1)
163
166
  hitimes
164
167
  tins (1.6.0)
165
168
  tzinfo (1.2.2)
@@ -222,6 +222,7 @@ module Taskinator
222
222
  end
223
223
  end
224
224
 
225
+ # this method only called in-process (usually from the console)
225
226
  def start
226
227
  if tasks.empty?
227
228
  complete! # weren't any tasks to start with
@@ -247,7 +248,17 @@ module Taskinator
247
248
  def task_completed(task)
248
249
  # when complete on first, then don't bother with subsequent tasks completing
249
250
  return if completed? || failed?
250
- complete!
251
+
252
+ if tasks_completed?
253
+ # prevent re-entrance so that two tasks completing
254
+ # simultaneously can't complete the process twice,
255
+ # which enqueues/starts the same subsequent task
256
+ Taskinator.redis_mutex(uuid) do
257
+ # double check, since the status may have
258
+ # changed while waiting in the mutex
259
+ complete! if tasks_completed?
260
+ end
261
+ end
251
262
  end
252
263
 
253
264
  def tasks_completed?
@@ -1,3 +1,3 @@
1
1
  module Taskinator
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
@@ -2,7 +2,8 @@ module Taskinator
2
2
  module Workflow
3
3
 
4
4
  def current_state
5
- @current_state ||= load_workflow_state
5
+ # NB: don't memoize this value (i.e. re-read it each time)
6
+ @current_state = load_workflow_state
6
7
  end
7
8
 
8
9
  def current_state=(new_state)
data/lib/taskinator.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'yaml'
3
3
  require 'securerandom'
4
+ require 'redis-semaphore'
4
5
 
5
6
  require 'taskinator/version'
6
7
 
@@ -62,6 +63,13 @@ module Taskinator
62
63
  redis_pool.with(&block)
63
64
  end
64
65
 
66
+ def redis_mutex(lockid, options={}, &block)
67
+ raise ArgumentError, "requires a block" unless block_given?
68
+ redis do |r|
69
+ Redis::Semaphore.new(lockid, {:redis => r}.merge(options)).lock(&block)
70
+ end
71
+ end
72
+
65
73
  def redis_pool
66
74
  @redis ||= Taskinator::RedisConnection.create
67
75
  end
@@ -344,7 +344,9 @@ describe Taskinator::Process do
344
344
 
345
345
  describe Taskinator::Process::Concurrent do
346
346
 
347
- subject { Taskinator::Process.define_concurrent_process_for(definition) }
347
+ let(:complete_on) { Taskinator::CompleteOn::Default }
348
+
349
+ subject { Taskinator::Process.define_concurrent_process_for(definition, complete_on) }
348
350
 
349
351
  it_should_behave_like "a process", Taskinator::Process::Concurrent do
350
352
 
@@ -414,12 +416,33 @@ describe Taskinator::Process do
414
416
  end
415
417
 
416
418
  describe "#task_completed" do
417
- it "completes when tasks complete" do
418
- tasks.each {|t| subject.tasks << t }
419
+ it "completes when tasks complete (CompleteOn::First)" do
420
+ allow_any_instance_of(Taskinator::Task).to receive(:completed?) { true }
419
421
 
420
- expect(subject).to receive(:complete!)
422
+ process = Taskinator::Process.define_concurrent_process_for(definition, Taskinator::CompleteOn::First)
423
+ tasks.each {|t| process.tasks << t }
424
+
425
+ expect(process).to receive(:complete!).and_call_original
426
+
427
+ process.task_completed(tasks.first)
428
+
429
+ # remaining tasks should do nothing...
430
+ tasks.each do |task|
431
+ process.task_completed(task)
432
+ end
433
+ end
434
+
435
+ it "completes when tasks complete (CompleteOn::Last)" do
436
+ allow_any_instance_of(Taskinator::Task).to receive(:completed?) { true }
421
437
 
422
- subject.task_completed(tasks.first)
438
+ process = Taskinator::Process.define_concurrent_process_for(definition, Taskinator::CompleteOn::Last)
439
+ tasks.each {|t| process.tasks << t }
440
+
441
+ expect(process).to receive(:complete!).and_call_original
442
+
443
+ tasks.each do |task|
444
+ process.task_completed(task)
445
+ end
423
446
  end
424
447
  end
425
448
 
data/taskinator.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  # core
24
24
  spec.add_dependency 'redis' , '>= 3.2.1'
25
25
  spec.add_dependency 'redis-namespace' , '>= 1.5.2'
26
+ spec.add_dependency 'redis-semaphore' , '>= 0.2.4'
26
27
  spec.add_dependency 'connection_pool' , '>= 2.2.0'
27
28
  spec.add_dependency 'json' , '>= 1.8.2'
28
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taskinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Stefano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-01 00:00:00.000000000 Z
11
+ date: 2015-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.5.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: redis-semaphore
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.2.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.2.4
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: connection_pool
43
57
  requirement: !ruby/object:Gem::Requirement