status_workflow 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/CHANGELOG +6 -0
- data/README.md +2 -0
- data/lib/status_workflow.rb +39 -10
- data/lib/status_workflow/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31fac79b181eaf226d6f199406c58b23f2860674
|
4
|
+
data.tar.gz: abb35fc730390397b21692c0a0f398a9628253e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7f31170e7845fcd47a2f0f9ab5e68c08b6a7eae0226f784b8060d563a4ffa812ca21d7ff79230e248fb899d2a325d57299ce830ade5ffb4776d412247889a85
|
7
|
+
data.tar.gz: 271e5943314d59d02ca2a8e48e2cd5750077fbea2986605c2ca3d0074de16efca5bbb407cbd5fc76b6d1316bb4a80629c8ddff2d877b574a9d9e7da5c1b9f50c
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG
CHANGED
data/README.md
CHANGED
data/lib/status_workflow.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'status_workflow/version'
|
2
2
|
require 'timeout'
|
3
|
+
require 'set'
|
3
4
|
|
4
5
|
module StatusWorkflow
|
5
6
|
class InvalidTransition < StandardError; end
|
@@ -16,29 +17,57 @@ module StatusWorkflow
|
|
16
17
|
@redis or raise("please set StatusWorkflow.redis=")
|
17
18
|
end
|
18
19
|
|
20
|
+
LOCK_ACQUISITION_TIMEOUT = 8
|
21
|
+
LOCK_EXPIRY = 4
|
22
|
+
LOCK_CHECK_RATE = 0.2
|
23
|
+
|
19
24
|
module ClassMethods
|
20
25
|
def status_workflow(transitions)
|
21
26
|
transitions.inject({}) do |memo, (from_status, to_statuses)|
|
22
27
|
to_statuses.each do |to_status|
|
23
|
-
memo[to_status] ||=
|
28
|
+
memo[to_status] ||= Set.new
|
24
29
|
memo[to_status] << from_status
|
25
30
|
end
|
26
31
|
memo
|
27
32
|
end.each do |to_status, from_statuses|
|
28
|
-
define_method "enter_#{to_status}!" do
|
33
|
+
define_method "enter_#{to_status}!" do |&blk|
|
29
34
|
lock_key = "status_workflow/#{self.class.name}/#{id}"
|
30
|
-
|
31
|
-
|
32
|
-
|
35
|
+
# Give ourselves 8 seconds to get the lock, checking every 0.2 seconds
|
36
|
+
Timeout.timeout(LOCK_ACQUISITION_TIMEOUT, nil, "timeout waiting for #{self.class.name}/#{id} lock") do
|
37
|
+
until StatusWorkflow.redis.set(lock_key, true, nx: true, ex: LOCK_EXPIRY)
|
38
|
+
sleep LOCK_CHECK_RATE
|
33
39
|
end
|
34
40
|
end
|
35
|
-
|
36
|
-
|
37
|
-
#
|
38
|
-
|
41
|
+
heartbeat = nil
|
42
|
+
begin
|
43
|
+
# Give ourselves 2 seconds to check the status of the lock
|
44
|
+
Timeout.timeout(2, nil, "timeout waiting for #{self.class.name}/#{id} status check") do
|
45
|
+
# depend on #can_enter_X to reload
|
46
|
+
raise InvalidTransition, "can't enter #{to_status} from #{status}, expected #{from_statuses.to_a.join('/')}" unless send("can_enter_#{to_status}?")
|
47
|
+
end
|
48
|
+
# If a block was given, start a heartbeat thread
|
49
|
+
if blk
|
50
|
+
begin
|
51
|
+
heartbeat = Thread.new do
|
52
|
+
loop do
|
53
|
+
StatusWorkflow.redis.expire lock_key, LOCK_EXPIRY
|
54
|
+
sleep LOCK_EXPIRY/2
|
55
|
+
end
|
56
|
+
end
|
57
|
+
blk.call
|
58
|
+
rescue
|
59
|
+
# If the block errors, set status to error and record the backtrace
|
60
|
+
error = (["#{$!.class} #{$!.message}"] + $!.backtrace).join("\n")
|
61
|
+
update_columns status: 'error', status_changed_at: Time.now, error: error
|
62
|
+
raise
|
63
|
+
end
|
64
|
+
end
|
65
|
+
# Success!
|
39
66
|
update_columns status: to_status, status_changed_at: Time.now
|
67
|
+
ensure
|
68
|
+
StatusWorkflow.redis.del lock_key
|
69
|
+
heartbeat.kill if heartbeat
|
40
70
|
end
|
41
|
-
StatusWorkflow.redis.del lock_key
|
42
71
|
true
|
43
72
|
end
|
44
73
|
define_method "can_enter_#{to_status}?" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: status_workflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Seamus Abshere
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|