capistrano_multiconfig_parallel 0.1.4 → 0.2.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 +4 -4
- data/lib/capistrano_multiconfig_parallel/base.rb +6 -3
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_manager.rb +32 -11
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_worker.rb +20 -48
- data/lib/capistrano_multiconfig_parallel/celluloid/child_process.rb +0 -8
- data/lib/capistrano_multiconfig_parallel/cli.rb +0 -1
- data/lib/capistrano_multiconfig_parallel/helpers/base_manager.rb +1 -0
- data/lib/capistrano_multiconfig_parallel/version.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5a35a7ede67c601da4e663947e5e58fb0e83065
|
4
|
+
data.tar.gz: 9307b72fb8716cf0117307eb5d9a5c86169b5601
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ac2faaeabb21aae54db13122d077fd0a93d973fd172f54bd38c12d75fbbaa28f035eba4da08f643ad977e01f97300d45fa046ff6c0e986fa690e3d03277b046
|
7
|
+
data.tar.gz: dc6cbf259342a4f4e44e663e97a41b7295cb42286fb164f0780de80c4e631348b156fe74bcf5b5e778d92f049cb874ed956afbac76681fa0cec6a1d03eaa486b
|
@@ -56,9 +56,12 @@ module CapistranoMulticonfigParallel
|
|
56
56
|
def enable_logging
|
57
57
|
CapistranoMulticonfigParallel.configuration_valid?
|
58
58
|
return unless CapistranoMulticonfigParallel::CelluloidManager.debug_enabled
|
59
|
-
FileUtils.mkdir_p(log_directory)
|
60
|
-
|
61
|
-
|
59
|
+
FileUtils.mkdir_p(log_directory) unless File.directory?(log_directory)
|
60
|
+
FileUtils.touch(main_log_file) unless File.file?(main_log_file)
|
61
|
+
if ENV[CapistranoMulticonfigParallel::ENV_KEY_JOB_ID].blank?
|
62
|
+
log_file = File.open(main_log_file, 'w')
|
63
|
+
log_file.sync = true
|
64
|
+
end
|
62
65
|
self.logger = ::Logger.new(main_log_file)
|
63
66
|
Celluloid.logger = logger
|
64
67
|
end
|
@@ -90,32 +90,52 @@ module CapistranoMulticonfigParallel
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def process_jobs(&block)
|
93
|
-
@job_to_worker.pmap do |
|
93
|
+
@job_to_worker.pmap do |job_id, worker|
|
94
|
+
setup_worker_conditions(job_id)
|
94
95
|
worker.async.start_task
|
95
96
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
wait_task_confirmations
|
97
|
+
block_given? ? block.call : wait_task_confirmations
|
98
|
+
until @job_to_worker.all?{|job_id, worker| worker.alive? && worker.worker_state =='finished'}
|
99
|
+
sleep(0.1) # keep current thread alive
|
100
100
|
end
|
101
|
-
|
102
|
-
@
|
103
|
-
|
101
|
+
mark_completed_remaining_tasks
|
102
|
+
@job_manager.condition.signal("completed")
|
103
|
+
end
|
104
|
+
|
105
|
+
def setup_worker_conditions(job_id)
|
106
|
+
hash_conditions = {}
|
107
|
+
if need_confirmations?
|
108
|
+
CapistranoMulticonfigParallel.configuration.task_confirmations.each do |task|
|
109
|
+
hash_conditions[task] = { condition: Celluloid::Condition.new, status: 'unconfirmed' }
|
110
|
+
end
|
104
111
|
end
|
105
|
-
@
|
112
|
+
@job_to_condition[job_id] = hash_conditions
|
106
113
|
end
|
107
114
|
|
108
115
|
def need_confirmations?
|
109
116
|
CapistranoMulticonfigParallel.configuration.task_confirmation_active.to_s.downcase == 'true'
|
110
117
|
end
|
111
118
|
|
119
|
+
def mark_completed_remaining_tasks
|
120
|
+
return unless need_confirmations?
|
121
|
+
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, index|
|
122
|
+
@jobs.pmap do |job_id, _job|
|
123
|
+
fake_result = proc{ |sum| sum }
|
124
|
+
task_confirmation = @job_to_condition[job_id][task]
|
125
|
+
if task_confirmation[:status] != 'confirmed'
|
126
|
+
task_confirmation[:status] = 'confirmed'
|
127
|
+
task_confirmation[:condition].signal(fake_result)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
112
133
|
def wait_task_confirmations
|
113
134
|
return unless need_confirmations?
|
114
135
|
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, index|
|
115
136
|
results = []
|
116
137
|
@jobs.pmap do |job_id, _job|
|
117
|
-
|
118
|
-
result = current_job.respond_to?(:wait) ? current_job.wait : current_job
|
138
|
+
result = @job_to_condition[job_id][task][:condition].wait
|
119
139
|
results << result
|
120
140
|
end
|
121
141
|
if results.size == @jobs.size
|
@@ -124,6 +144,7 @@ module CapistranoMulticonfigParallel
|
|
124
144
|
end
|
125
145
|
end
|
126
146
|
|
147
|
+
|
127
148
|
def confirm_task_approval(results, task)
|
128
149
|
return unless results.present?
|
129
150
|
if results.detect {|x| !x.is_a?(Proc)}
|
@@ -23,19 +23,19 @@ module CapistranoMulticonfigParallel
|
|
23
23
|
class TaskFailed < StandardError; end
|
24
24
|
|
25
25
|
attr_accessor :job, :manager, :job_id, :app_name, :env_name, :action_name, :env_options, :machine, :client, :task_argv, :execute_deploy, :executed_dry_run,
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
:rake_tasks, :current_task_number, # tracking tasks
|
27
|
+
:successfull_subscription, :subscription_channel, :publisher_channel, # for subscriptions and publishing events
|
28
|
+
:job_termination_condition, :worker_state
|
29
29
|
|
30
30
|
def work(job, manager)
|
31
31
|
@job = job
|
32
|
+
@worker_state = 'started'
|
32
33
|
@manager = manager
|
33
|
-
|
34
|
+
@job_confirmation_conditions = []
|
34
35
|
process_job(job) if job.present?
|
35
36
|
debug("worker #{@job_id} received #{job.inspect}") if debug_enabled?
|
36
37
|
@subscription_channel = "worker_#{@job_id}"
|
37
38
|
@machine = CapistranoMulticonfigParallel::StateMachine.new(job, Actor.current)
|
38
|
-
setup_worker_condition
|
39
39
|
manager.register_worker_for_job(job, Actor.current)
|
40
40
|
end
|
41
41
|
|
@@ -45,7 +45,6 @@ module CapistranoMulticonfigParallel
|
|
45
45
|
|
46
46
|
def start_task
|
47
47
|
debug("exec worker #{@job_id} starts task with #{@job.inspect}") if debug_enabled?
|
48
|
-
@task_confirmations = CapistranoMulticonfigParallel.configuration.task_confirmations
|
49
48
|
@client = CelluloidPubsub::Client.connect(actor: Actor.current, enable_debug: @manager.class.debug_websocket?) do |ws|
|
50
49
|
ws.subscribe(@subscription_channel)
|
51
50
|
end
|
@@ -124,8 +123,10 @@ module CapistranoMulticonfigParallel
|
|
124
123
|
end
|
125
124
|
|
126
125
|
def task_approval(message)
|
127
|
-
if
|
128
|
-
@
|
126
|
+
if CapistranoMulticonfigParallel.configuration.task_confirmations.include?(message['task']) && message['action'] == 'invoke'
|
127
|
+
task_confirmation = @manager.job_to_condition[@job_id][message['task']]
|
128
|
+
task_confirmation[:status] = 'confirmed'
|
129
|
+
task_confirmation[:condition].signal(message['task'])
|
129
130
|
else
|
130
131
|
publish_rake_event(message.merge('approved' => 'yes'))
|
131
132
|
end
|
@@ -181,43 +182,6 @@ module CapistranoMulticonfigParallel
|
|
181
182
|
@task_arguments = job['task_arguments']
|
182
183
|
end
|
183
184
|
|
184
|
-
def need_confirmation_for_tasks?
|
185
|
-
executes_deploy? == true && @manager.need_confirmations?
|
186
|
-
end
|
187
|
-
|
188
|
-
def executes_deploy?
|
189
|
-
(@action_name == 'deploy' || @action_name == 'deploy:rollback')
|
190
|
-
end
|
191
|
-
|
192
|
-
def setup_worker_condition
|
193
|
-
job_termination_condition = Celluloid::Condition.new
|
194
|
-
job_confirmation_conditions = []
|
195
|
-
CapistranoMulticonfigParallel.configuration.task_confirmations.each do |_task|
|
196
|
-
if need_confirmation_for_tasks?
|
197
|
-
job_confirmation_conditions << Celluloid::Condition.new
|
198
|
-
else
|
199
|
-
job_confirmation_conditions << proc { |sum| sum }
|
200
|
-
end
|
201
|
-
end
|
202
|
-
@manager.job_to_condition[@job_id] = { first_condition: job_confirmation_conditions, last_condition: job_termination_condition }
|
203
|
-
construct_blocks_for_conditions(job_confirmation_conditions, job_termination_condition)
|
204
|
-
end
|
205
|
-
|
206
|
-
def construct_blocks_for_conditions(job_confirmation_conditions, job_termination_condition)
|
207
|
-
hash_conditions = {}
|
208
|
-
CapistranoMulticonfigParallel.configuration.task_confirmations.each_with_index do |task, index|
|
209
|
-
blk = lambda do |sum|
|
210
|
-
need_confirmation_for_tasks? ? job_confirmation_conditions[index].signal(sum) : job_confirmation_conditions[index].call(sum)
|
211
|
-
end
|
212
|
-
hash_conditions[task] = blk
|
213
|
-
end
|
214
|
-
blk_termination = lambda do |sum|
|
215
|
-
job_termination_condition.signal(sum)
|
216
|
-
end
|
217
|
-
@manager_condition = hash_conditions
|
218
|
-
@last_manager_condition = blk_termination
|
219
|
-
end
|
220
|
-
|
221
185
|
def crashed?
|
222
186
|
@action_name == 'deploy:rollback'
|
223
187
|
end
|
@@ -225,13 +189,21 @@ module CapistranoMulticonfigParallel
|
|
225
189
|
def notify_finished(exit_status)
|
226
190
|
return unless @execute_deploy
|
227
191
|
if exit_status.exitstatus != 0
|
228
|
-
debug("worker #{job_id} tries to terminate")
|
192
|
+
debug("worker #{job_id} tries to terminate") if debug_enabled?
|
229
193
|
terminate
|
230
194
|
else
|
231
195
|
update_machine_state('FINISHED')
|
232
|
-
debug("worker #{job_id} notifies manager has finished")
|
233
|
-
@
|
196
|
+
debug("worker #{job_id} notifies manager has finished") if debug_enabled?
|
197
|
+
@worker_state = "finished"
|
198
|
+
if debug_enabled?
|
199
|
+
debug("worker #{job_id}has state #{@worker_state}")
|
200
|
+
@manager.job_to_worker.each{|job_id, worker|
|
201
|
+
debug("worker #{worker.job_id}has state #{worker.worker_state}") if worker.alive?
|
202
|
+
}
|
203
|
+
end
|
234
204
|
end
|
235
205
|
end
|
206
|
+
|
207
|
+
|
236
208
|
end
|
237
209
|
end
|
@@ -6,14 +6,6 @@ module CapistranoMulticonfigParallel
|
|
6
6
|
|
7
7
|
attr_accessor :actor, :pid, :exit_status, :process, :filename,:worker_log
|
8
8
|
|
9
|
-
def finalize
|
10
|
-
EM.stop
|
11
|
-
@timer.cancel
|
12
|
-
super
|
13
|
-
true
|
14
|
-
end
|
15
|
-
|
16
|
-
alias_method :terminate, :finalize
|
17
9
|
|
18
10
|
def work(cmd, options = {})
|
19
11
|
@options = options
|
@@ -13,6 +13,7 @@ module CapistranoMulticonfigParallel
|
|
13
13
|
@top_level_tasks = top_level_tasks
|
14
14
|
@stages = stages
|
15
15
|
@jobs = []
|
16
|
+
CapistranoMulticonfigParallel.enable_logging
|
16
17
|
CapistranoMulticonfigParallel.configuration_valid?
|
17
18
|
CapistranoMulticonfigParallel.verify_app_dependencies(@stages) if CapistranoMulticonfigParallel.configuration.track_dependencies
|
18
19
|
end
|