abid 0.2.3 → 0.2.4
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 +4 -4
- data/.gitignore +1 -0
- data/lib/abid.rb +1 -1
- data/lib/abid/play.rb +1 -10
- data/lib/abid/rake_extensions/task.rb +79 -71
- data/lib/abid/session.rb +92 -0
- data/lib/abid/state.rb +5 -20
- data/lib/abid/task.rb +24 -12
- data/lib/abid/version.rb +1 -1
- metadata +3 -4
- data/lib/abid/concurrent_extention.rb +0 -6
- data/lib/abid/concurrent_extention/ivar.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c41573b12be68e4e74a00c7d8014e7f2d3cc435
|
4
|
+
data.tar.gz: b9e43e1b4d742c798972984090eab802245db56f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ea210978f2e500611a2ccee925413d8e1e85dcb54cc770ca626622ca588c52650324925c00aa5a47178e732cdf0adaa88fe0a7c79436fd399785d888426ff38
|
7
|
+
data.tar.gz: f5fd045370053a9fd27e88d007a071bb888f4b658082ed331d1b81aff6ee303fa040705908f64be6d3af21b3ea2f2dfd9ee80dff2597e4c13d3084cc97a20cca
|
data/.gitignore
CHANGED
data/lib/abid.rb
CHANGED
@@ -13,13 +13,13 @@ require 'sqlite3'
|
|
13
13
|
require 'sequel'
|
14
14
|
|
15
15
|
require 'abid/rake_extensions'
|
16
|
-
require 'abid/concurrent_extention'
|
17
16
|
require 'abid/version'
|
18
17
|
require 'abid/abid_module'
|
19
18
|
require 'abid/waiter'
|
20
19
|
require 'abid/worker'
|
21
20
|
require 'abid/params_parser'
|
22
21
|
require 'abid/play'
|
22
|
+
require 'abid/session'
|
23
23
|
require 'abid/state'
|
24
24
|
require 'abid/task'
|
25
25
|
require 'abid/task_manager'
|
data/lib/abid/play.rb
CHANGED
@@ -25,12 +25,7 @@ module Abid
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def hooks
|
28
|
-
@hooks ||= {
|
29
|
-
setup: [],
|
30
|
-
before: [],
|
31
|
-
after: [],
|
32
|
-
around: []
|
33
|
-
}
|
28
|
+
@hooks ||= Hash.new { |h, k| h[k] = [] }
|
34
29
|
end
|
35
30
|
|
36
31
|
def set(name, value = nil, &block)
|
@@ -65,10 +60,6 @@ module Abid
|
|
65
60
|
hooks[:after] << block
|
66
61
|
end
|
67
62
|
|
68
|
-
def around(&block)
|
69
|
-
hooks[:around] << block
|
70
|
-
end
|
71
|
-
|
72
63
|
def method_added(name)
|
73
64
|
params_spec.delete(name) # undef param
|
74
65
|
end
|
@@ -9,6 +9,16 @@ module Abid
|
|
9
9
|
:default
|
10
10
|
end
|
11
11
|
|
12
|
+
def session
|
13
|
+
@session ||= Session.new(self).tap do |session|
|
14
|
+
session.add_observer do |_, _, reason|
|
15
|
+
if session.successed? || session.failed?
|
16
|
+
call_hooks(:after_invoke, reason)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
12
22
|
def state
|
13
23
|
State.find(self)
|
14
24
|
end
|
@@ -17,102 +27,98 @@ module Abid
|
|
17
27
|
name
|
18
28
|
end
|
19
29
|
|
30
|
+
def concerned?
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def top_level?
|
35
|
+
application.top_level_tasks.any? { |t| application[t] == self }
|
36
|
+
end
|
37
|
+
|
38
|
+
def hooks
|
39
|
+
@hooks ||= Hash.new { |h, k| h[k] = [] }
|
40
|
+
end
|
41
|
+
|
42
|
+
def call_hooks(tag, *args)
|
43
|
+
hooks[tag].each { |h| h.call(*args) }
|
44
|
+
end
|
45
|
+
|
20
46
|
def async_invoke(*args)
|
21
47
|
task_args = Rake::TaskArguments.new(arg_names, args)
|
22
48
|
async_invoke_with_call_chain(task_args, Rake::InvocationChain::EMPTY)
|
23
49
|
end
|
24
50
|
|
25
51
|
def async_invoke_with_call_chain(task_args, invocation_chain)
|
26
|
-
|
27
|
-
|
28
|
-
|
52
|
+
session.enter do
|
53
|
+
session.capture_exception do
|
54
|
+
new_chain = Rake::InvocationChain.append(self, invocation_chain)
|
29
55
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
elsif !application.options.repair && state.failed? && !invocation_chain.empty?
|
35
|
-
# fail if not top level
|
36
|
-
fail "#{name} -- task has been failed" rescue state.ivar.try_fail($ERROR_INFO)
|
37
|
-
else
|
38
|
-
async_invoke_with_prerequisites(task_args, new_chain)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
state.ivar
|
42
|
-
ensure
|
43
|
-
state.ivar.try_fail($ERROR_INFO) if $ERROR_INFO
|
44
|
-
end
|
56
|
+
unless concerned?
|
57
|
+
session.skip
|
58
|
+
break
|
59
|
+
end
|
45
60
|
|
46
|
-
|
47
|
-
application.trace "** Invoke #{name_with_params}" if application.options.trace
|
61
|
+
call_hooks(:before_invoke)
|
48
62
|
|
49
|
-
|
63
|
+
async_invoke_prerequisites(task_args, new_chain)
|
50
64
|
|
51
|
-
|
52
|
-
if state.successed? && !updated
|
53
|
-
application.trace "** Skip #{name_with_params}" if application.options.trace
|
54
|
-
state.ivar.try_set(false)
|
55
|
-
else
|
56
|
-
async_invoke_tasks(volatiles, task_args, invocation_chain) do
|
57
|
-
async_execute_with_session(task_args)
|
58
|
-
end
|
65
|
+
async_execute_after_prerequisites(task_args)
|
59
66
|
end
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
63
|
-
def
|
64
|
-
|
70
|
+
def async_invoke_prerequisites(task_args, invocation_chain)
|
71
|
+
prerequisite_tasks.each do |t|
|
65
72
|
args = task_args.new_scope(t.arg_names)
|
66
73
|
t.async_invoke_with_call_chain(args, invocation_chain)
|
67
74
|
end
|
75
|
+
end
|
68
76
|
|
69
|
-
|
70
|
-
|
77
|
+
def async_execute_after_prerequisites(task_args)
|
78
|
+
if prerequisite_tasks.empty?
|
79
|
+
async_execute(task_args)
|
71
80
|
else
|
72
|
-
counter = Concurrent::DependencyCounter.new(
|
73
|
-
|
74
|
-
|
75
|
-
state.ivar.try_fail(ivars.find(&:rejected?).reason)
|
76
|
-
else
|
77
|
-
updated = ivars.map(&:value).any?
|
78
|
-
block.call(updated)
|
79
|
-
end
|
80
|
-
rescue Exception => err
|
81
|
-
state.ivar.try_fail(err)
|
81
|
+
counter = Concurrent::DependencyCounter.new(prerequisite_tasks.size) do
|
82
|
+
session.capture_exception do
|
83
|
+
async_execute(task_args)
|
82
84
|
end
|
83
85
|
end
|
84
|
-
|
86
|
+
prerequisite_tasks.each { |t| t.session.add_observer counter }
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
90
|
+
def async_execute(task_args)
|
91
|
+
failed_task = prerequisite_tasks.find do |t|
|
92
|
+
t.session.failed? || t.session.canceled?
|
93
|
+
end
|
94
|
+
if failed_task
|
95
|
+
session.cancel(failed_task.session.error)
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
99
|
+
async_post(worker) do
|
100
|
+
if !needed?
|
101
|
+
session.skip
|
102
|
+
elsif session.lock
|
103
|
+
call_hooks(:before_execute)
|
104
|
+
|
105
|
+
execute(task_args)
|
99
106
|
|
100
|
-
|
101
|
-
|
102
|
-
|
107
|
+
session.success
|
108
|
+
else
|
109
|
+
async_wait_external
|
103
110
|
end
|
104
111
|
end
|
105
112
|
end
|
106
113
|
|
107
|
-
def
|
114
|
+
def async_wait_external
|
108
115
|
unless application.options.wait_external_task
|
109
|
-
|
110
|
-
return state.ivar.try_fail(err)
|
116
|
+
fail "task #{name_with_params} already running"
|
111
117
|
end
|
112
118
|
|
113
119
|
application.trace "** Wait #{name_with_params}" if application.options.trace
|
114
120
|
|
115
|
-
|
121
|
+
async_post(:waiter) do
|
116
122
|
interval = application.options.wait_external_task_interval || 10
|
117
123
|
timeout = application.options.wait_external_task_timeout || 3600
|
118
124
|
timeout_tm = Time.now.to_f + timeout
|
@@ -120,11 +126,10 @@ module Abid
|
|
120
126
|
loop do
|
121
127
|
state.reload
|
122
128
|
if !state.running?
|
123
|
-
|
129
|
+
session.success
|
124
130
|
break
|
125
131
|
elsif Time.now.to_f >= timeout_tm
|
126
|
-
fail "#{name} -- timeout exceeded"
|
127
|
-
break
|
132
|
+
fail "#{name} -- timeout exceeded"
|
128
133
|
else
|
129
134
|
sleep interval
|
130
135
|
end
|
@@ -132,12 +137,15 @@ module Abid
|
|
132
137
|
end
|
133
138
|
end
|
134
139
|
|
135
|
-
def
|
136
|
-
application.worker[
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
140
|
+
def async_post(worker_name, &block)
|
141
|
+
application.worker[worker_name].post do
|
142
|
+
session.capture_exception do
|
143
|
+
begin
|
144
|
+
block.call
|
145
|
+
finished = true
|
146
|
+
ensure
|
147
|
+
fail 'thread killed' if $ERROR_INFO.nil? && !finished
|
148
|
+
end
|
141
149
|
end
|
142
150
|
end
|
143
151
|
end
|
data/lib/abid/session.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Abid
|
2
|
+
class Session
|
3
|
+
extend MonitorMixin
|
4
|
+
|
5
|
+
%w(successed skipped failed canceled).each do |result|
|
6
|
+
define_method(:"#{result}?") { @result == result.to_sym }
|
7
|
+
end
|
8
|
+
attr_reader :error
|
9
|
+
|
10
|
+
def initialize(task)
|
11
|
+
@task = task
|
12
|
+
@state = task.state
|
13
|
+
|
14
|
+
@entered = false
|
15
|
+
@locked = false
|
16
|
+
@result = nil
|
17
|
+
@error = nil
|
18
|
+
@ivar = Concurrent::IVar.new
|
19
|
+
|
20
|
+
@on_success = []
|
21
|
+
@on_fail = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def synchronize(&block)
|
25
|
+
self.class.synchronize(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def enter(&block)
|
29
|
+
synchronize do
|
30
|
+
return @ivar if @entered
|
31
|
+
@entered = true
|
32
|
+
end
|
33
|
+
block.call
|
34
|
+
@ivar
|
35
|
+
end
|
36
|
+
|
37
|
+
def capture_exception(&block)
|
38
|
+
block.call
|
39
|
+
rescue Exception => e
|
40
|
+
self.fail(e)
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_observer(*args, &block)
|
44
|
+
@ivar.add_observer(*args, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def lock
|
48
|
+
synchronize do
|
49
|
+
@state.start unless @locked
|
50
|
+
@locked = true
|
51
|
+
true
|
52
|
+
end
|
53
|
+
rescue AbidErrorTaskAlreadyRunning
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
def unlock(error = nil)
|
58
|
+
synchronize do
|
59
|
+
@state.finish(error) if @locked
|
60
|
+
@locked = false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def success
|
65
|
+
unlock
|
66
|
+
@result = :successed
|
67
|
+
@ivar.try_set(true)
|
68
|
+
end
|
69
|
+
|
70
|
+
def skip
|
71
|
+
unlock
|
72
|
+
@result = :skipped
|
73
|
+
@ivar.try_set(false)
|
74
|
+
end
|
75
|
+
|
76
|
+
def fail(error)
|
77
|
+
@result = :failed
|
78
|
+
@error = error
|
79
|
+
unlock(error)
|
80
|
+
@ivar.fail(error) rescue Concurrent::MultipleAssignmentError
|
81
|
+
rescue Exception => e
|
82
|
+
@ivar.fail(e) rescue Concurrent::MultipleAssignmentError
|
83
|
+
end
|
84
|
+
|
85
|
+
def cancel(error)
|
86
|
+
unlock(error)
|
87
|
+
@result = :canceled
|
88
|
+
@error = error
|
89
|
+
@ivar.fail(error) rescue Concurrent::MultipleAssignmentError
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/abid/state.rb
CHANGED
@@ -56,24 +56,14 @@ module Abid
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def_delegators 'self.class', :serialize, :deserialize
|
59
|
-
attr_reader :ivar
|
60
59
|
|
61
60
|
def initialize(task)
|
62
61
|
@task = task
|
63
62
|
@record = nil
|
64
|
-
@
|
65
|
-
@already_invoked = false
|
63
|
+
@started = false
|
66
64
|
reload
|
67
65
|
end
|
68
66
|
|
69
|
-
def only_once(&block)
|
70
|
-
self.class.synchronize do
|
71
|
-
return if @already_invoked
|
72
|
-
@already_invoked = true
|
73
|
-
end
|
74
|
-
block.call
|
75
|
-
end
|
76
|
-
|
77
67
|
def database
|
78
68
|
Rake.application.database
|
79
69
|
end
|
@@ -155,14 +145,7 @@ module Abid
|
|
155
145
|
end
|
156
146
|
end
|
157
147
|
|
158
|
-
def
|
159
|
-
started = start_session
|
160
|
-
block.call
|
161
|
-
ensure
|
162
|
-
close_session($ERROR_INFO) if started
|
163
|
-
end
|
164
|
-
|
165
|
-
def start_session
|
148
|
+
def start
|
166
149
|
return true if disabled? || preview?
|
167
150
|
|
168
151
|
database.transaction do
|
@@ -189,13 +172,15 @@ module Abid
|
|
189
172
|
@record = { id: id, **new_state }
|
190
173
|
end
|
191
174
|
|
175
|
+
@started = true
|
192
176
|
true
|
193
177
|
end
|
194
178
|
end
|
195
179
|
|
196
|
-
def
|
180
|
+
def finish(error = nil)
|
197
181
|
return if disabled? || preview?
|
198
182
|
return unless @record
|
183
|
+
return unless @started
|
199
184
|
state = error ? FAILED : SUCCESSED
|
200
185
|
dataset.where(id: @record[:id]).update(state: state, end_time: Time.now)
|
201
186
|
reload
|
data/lib/abid/task.rb
CHANGED
@@ -39,8 +39,10 @@ module Abid
|
|
39
39
|
@prerequisites = []
|
40
40
|
@params = sorted_params
|
41
41
|
@play = play_class.new(t)
|
42
|
+
call_play_hooks(:setup)
|
43
|
+
bind_play_hooks(:before, :before_execute)
|
44
|
+
bind_play_hooks(:after, :after_invoke)
|
42
45
|
end
|
43
|
-
play_class.hooks[:setup].each { |blk| t.play.instance_eval(&blk) }
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
@@ -97,22 +99,32 @@ module Abid
|
|
97
99
|
application.trace "** Execute #{name_with_params}"
|
98
100
|
end
|
99
101
|
|
100
|
-
|
102
|
+
play.run
|
103
|
+
end
|
104
|
+
|
105
|
+
def concerned?
|
106
|
+
state.reload
|
101
107
|
|
102
|
-
|
108
|
+
if !application.options.repair && state.failed? && !top_level?
|
109
|
+
fail "#{name} -- task has been failed"
|
110
|
+
end
|
103
111
|
|
104
|
-
|
112
|
+
application.options.repair || !state.successed?
|
105
113
|
end
|
106
114
|
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
115
|
+
def needed?
|
116
|
+
!state.successed? || prerequisite_tasks.any? { |t| t.session.successed? }
|
117
|
+
end
|
118
|
+
|
119
|
+
def bind_play_hooks(tag, to = nil)
|
120
|
+
to ||= tag
|
121
|
+
hooks[to] = [proc { |*args| call_play_hooks(tag, *args) }]
|
122
|
+
end
|
123
|
+
|
124
|
+
def call_play_hooks(tag, *args)
|
125
|
+
return unless bound?
|
126
|
+
play_class.hooks[tag].each { |blk| play.instance_exec(*args, &blk) }
|
114
127
|
end
|
115
|
-
private :call_around_hooks
|
116
128
|
|
117
129
|
class <<self
|
118
130
|
def define_play(*args, &block) # :nodoc:
|
data/lib/abid/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hikaru Ojima
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -159,13 +159,12 @@ files:
|
|
159
159
|
- lib/abid.rb
|
160
160
|
- lib/abid/abid_module.rb
|
161
161
|
- lib/abid/application.rb
|
162
|
-
- lib/abid/concurrent_extention.rb
|
163
|
-
- lib/abid/concurrent_extention/ivar.rb
|
164
162
|
- lib/abid/dsl_definition.rb
|
165
163
|
- lib/abid/params_parser.rb
|
166
164
|
- lib/abid/play.rb
|
167
165
|
- lib/abid/rake_extensions.rb
|
168
166
|
- lib/abid/rake_extensions/task.rb
|
167
|
+
- lib/abid/session.rb
|
169
168
|
- lib/abid/state.rb
|
170
169
|
- lib/abid/task.rb
|
171
170
|
- lib/abid/task_manager.rb
|