capistrano_multiconfig_parallel 0.23.4 → 0.24.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/.rubocop.yml +3 -0
- data/lib/capistrano_multiconfig_parallel/application.rb +12 -8
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_manager.rb +8 -8
- data/lib/capistrano_multiconfig_parallel/celluloid/celluloid_worker.rb +4 -5
- data/lib/capistrano_multiconfig_parallel/celluloid/child_process.rb +34 -12
- data/lib/capistrano_multiconfig_parallel/celluloid/rake_worker.rb +14 -42
- data/lib/capistrano_multiconfig_parallel/celluloid/terminal_table.rb +19 -12
- data/lib/capistrano_multiconfig_parallel/classes/job.rb +10 -27
- data/lib/capistrano_multiconfig_parallel/helpers/application_helper.rb +13 -0
- data/lib/capistrano_multiconfig_parallel/helpers/core_helper.rb +1 -5
- data/lib/capistrano_multiconfig_parallel/version.rb +2 -2
- 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: 10e0f45b56213ac92e9ca67846cfd2de1c7df368
|
4
|
+
data.tar.gz: c90e83e1cef6d093af08cb6294c3f8f2066f90a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9591eeed7ec5e34a4e48d84220a2a8f9d385ef565436e3d95ac4d19708bca5682e728938df816f5d1d2ff0dc6f418a69adced59026acfaa63f1a95e6120b913d
|
7
|
+
data.tar.gz: 0650d360299158eafd25a6127c2c30c873c2c5502c35123fd538e7885e990c91d848797462d7cffe6cc8093cdcc0d3b59e80bf0c69cc40132c7e1c5a3e41cd0f
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'capistrano/multiconfig/dsl'
|
2
2
|
module CapistranoMulticonfigParallel
|
3
3
|
# finds app dependencies, shows menu and delegates jobs to celluloid manager
|
4
|
-
# rubocop:disable ClassLength
|
5
4
|
class Application
|
6
5
|
include Celluloid
|
7
6
|
include Celluloid::Logger
|
@@ -9,12 +8,14 @@ module CapistranoMulticonfigParallel
|
|
9
8
|
include Capistrano::DSL
|
10
9
|
include Capistrano::Multiconfig::DSL
|
11
10
|
|
12
|
-
attr_reader :stage_apps, :top_level_tasks, :jobs, :branch_backup, :condition, :manager, :dependency_tracker, :application, :stage, :name, :args, :argv, :default_stage
|
11
|
+
attr_reader :stage_apps, :top_level_tasks, :jobs, :branch_backup, :condition, :manager, :dependency_tracker, :application, :stage, :name, :args, :argv, :default_stage, :job_count
|
12
|
+
attr_writer :job_count
|
13
13
|
|
14
14
|
def initialize
|
15
15
|
Celluloid.boot
|
16
16
|
@stage_apps = multi_apps? ? stages.map { |stage| stage.split(':').reverse[1] }.uniq : []
|
17
17
|
collect_command_line_tasks(CapistranoMulticonfigParallel.original_args)
|
18
|
+
@job_count = 0
|
18
19
|
@jobs = []
|
19
20
|
end
|
20
21
|
|
@@ -191,11 +192,13 @@ module CapistranoMulticonfigParallel
|
|
191
192
|
@jobs.pmap do |job|
|
192
193
|
@manager.async.delegate(job)
|
193
194
|
end
|
194
|
-
|
195
|
-
|
195
|
+
unless can_tag_staging?
|
196
|
+
until @manager.registration_complete
|
197
|
+
sleep(0.1) # keep current thread alive
|
198
|
+
end
|
199
|
+
return unless @manager.registration_complete
|
200
|
+
@manager.async.process_jobs
|
196
201
|
end
|
197
|
-
return unless @manager.registration_complete
|
198
|
-
@manager.async.process_jobs
|
199
202
|
wait_jobs_termination
|
200
203
|
end
|
201
204
|
|
@@ -220,10 +223,11 @@ module CapistranoMulticonfigParallel
|
|
220
223
|
|
221
224
|
env_options = branch_name.present? ? { 'BRANCH' => branch_name }.merge(options['env_options']) : options['env_options']
|
222
225
|
job_env_options = custom_command? && env_options['ACTION'].present? ? env_options.except('ACTION') : env_options
|
223
|
-
|
226
|
+
@job_count += 1
|
224
227
|
job = CapistranoMulticonfigParallel::Job.new(Actor.current, options.merge(
|
225
228
|
action: custom_command? && env_options['ACTION'].present? ? env_options['ACTION'] : options['action'],
|
226
|
-
env_options: job_env_options
|
229
|
+
env_options: job_env_options,
|
230
|
+
count: @job_count
|
227
231
|
))
|
228
232
|
@jobs << job
|
229
233
|
end
|
@@ -3,7 +3,7 @@ require_relative './terminal_table'
|
|
3
3
|
require_relative './web_server'
|
4
4
|
require_relative '../helpers/application_helper'
|
5
5
|
module CapistranoMulticonfigParallel
|
6
|
-
#
|
6
|
+
# manager class that handles workers
|
7
7
|
class CelluloidManager
|
8
8
|
include Celluloid
|
9
9
|
include Celluloid::Notifications
|
@@ -44,23 +44,23 @@ module CapistranoMulticonfigParallel
|
|
44
44
|
@jobs[job.id] = job
|
45
45
|
# debug(@jobs)
|
46
46
|
# start work and send it to the background
|
47
|
-
@workers.
|
47
|
+
@workers.work(job, Actor.current)
|
48
48
|
end
|
49
49
|
|
50
50
|
# call back from actor once it has received it's job
|
51
51
|
# actor should do this asap
|
52
52
|
def register_worker_for_job(job, worker)
|
53
|
-
worker.job_id = job.id if worker.job_id.blank?
|
54
53
|
@job_to_worker[job.id] = worker
|
55
54
|
@worker_to_job[worker.mailbox.address] = job
|
56
55
|
log_to_file("worker #{worker.job_id} registed into manager")
|
57
56
|
Actor.current.link worker
|
58
57
|
worker.async.start_task if !syncronized_confirmation? || job.failed? || job.rolling_back?
|
59
|
-
|
58
|
+
return unless syncronized_confirmation?
|
59
|
+
@registration_complete = true if @job_manager.jobs.size == @jobs.size
|
60
60
|
end
|
61
61
|
|
62
62
|
def all_workers_finished?
|
63
|
-
@jobs.all? { |_job_id, job| job.finished? || job.crashed?
|
63
|
+
@jobs.all? { |_job_id, job| job.finished? || job.crashed? }
|
64
64
|
end
|
65
65
|
|
66
66
|
def process_jobs
|
@@ -193,9 +193,9 @@ module CapistranoMulticonfigParallel
|
|
193
193
|
return unless job.is_a?(CapistranoMulticonfigParallel::Job)
|
194
194
|
options.stringify_keys! if options.present?
|
195
195
|
env_opts = options['skip_env_options'].present? ? {} : @job_manager.get_app_additional_env_options(job.app, job.stage)
|
196
|
-
|
197
|
-
|
198
|
-
new_job.
|
196
|
+
@job_manager.job_count += 1
|
197
|
+
new_job_options = job.options.merge('env_options' => job.env_options.merge(env_opts), 'count' => @job_manager.job_count)
|
198
|
+
new_job = CapistranoMulticonfigParallel::Job.new(@job_manager, new_job_options.merge(options))
|
199
199
|
async.delegate(new_job) unless job.worker_died?
|
200
200
|
end
|
201
201
|
|
@@ -2,7 +2,6 @@ require_relative './child_process'
|
|
2
2
|
require_relative './state_machine'
|
3
3
|
require_relative '../helpers/application_helper'
|
4
4
|
module CapistranoMulticonfigParallel
|
5
|
-
# rubocop:disable ClassLength
|
6
5
|
# worker that will spawn a child process in order to execute a capistrano job and monitor that process
|
7
6
|
#
|
8
7
|
# @!attribute job
|
@@ -32,12 +31,13 @@ module CapistranoMulticonfigParallel
|
|
32
31
|
def work(job, manager)
|
33
32
|
@job = job
|
34
33
|
@job_id = job.id
|
35
|
-
@worker_state =
|
34
|
+
@worker_state = job.status
|
36
35
|
@manager = manager
|
37
36
|
@job_confirmation_conditions = []
|
38
37
|
log_to_file("worker #{@job_id} received #{job.inspect}")
|
39
38
|
@subscription_channel = "worker_#{@job_id}"
|
40
|
-
@machine = CapistranoMulticonfigParallel::StateMachine.new(job, Actor.current)
|
39
|
+
@machine = CapistranoMulticonfigParallel::StateMachine.new(@job, Actor.current)
|
40
|
+
@manager.setup_worker_conditions(@job)
|
41
41
|
manager.register_worker_for_job(job, Actor.current)
|
42
42
|
end
|
43
43
|
|
@@ -51,8 +51,7 @@ module CapistranoMulticonfigParallel
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def start_task
|
54
|
-
|
55
|
-
log_to_file("exec worker #{@job_id} starts task with #{@job.inspect}")
|
54
|
+
log_to_file("exec worker #{@job_id} starts task")
|
56
55
|
@client = CelluloidPubsub::Client.connect(actor: Actor.current, enable_debug: debug_websocket?, channel: subscription_channel)
|
57
56
|
end
|
58
57
|
|
@@ -14,27 +14,48 @@ module CapistranoMulticonfigParallel
|
|
14
14
|
def work(job, cmd, options = {})
|
15
15
|
@options = options
|
16
16
|
@job = job
|
17
|
+
@cmd = cmd
|
18
|
+
start_running
|
19
|
+
end
|
20
|
+
|
21
|
+
def start_running
|
22
|
+
setup_attributes
|
23
|
+
run_event_machine
|
24
|
+
setup_em_error_handler
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_attributes
|
17
28
|
@actor = @options.fetch(:actor, nil)
|
18
29
|
@job_id = @job.id
|
19
30
|
@exit_status = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def setup_em_error_handler
|
34
|
+
EM.error_handler do|exception|
|
35
|
+
log_to_file("Error during event loop for worker #{@job_id}: #{format_error(exception)}", job_id: @job_id)
|
36
|
+
EM.stop
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_event_machine
|
20
41
|
EM.run do
|
21
42
|
EM.next_tick do
|
22
|
-
start_async_deploy
|
23
|
-
end
|
24
|
-
@timer = EM::PeriodicTimer.new(0.1) do
|
25
|
-
check_exit_status
|
26
|
-
@timer.cancel if @exit_status.present?
|
43
|
+
start_async_deploy
|
27
44
|
end
|
45
|
+
setup_periodic_timer
|
28
46
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup_periodic_timer
|
50
|
+
@timer = EM::PeriodicTimer.new(0.1) do
|
51
|
+
check_exit_status
|
52
|
+
@timer.cancel if @exit_status.present?
|
33
53
|
end
|
34
54
|
end
|
35
55
|
|
36
56
|
def process_finalizer
|
37
57
|
EM.stop if EM.reactor_running?
|
58
|
+
terminate
|
38
59
|
end
|
39
60
|
|
40
61
|
def check_exit_status
|
@@ -45,11 +66,11 @@ module CapistranoMulticonfigParallel
|
|
45
66
|
@actor.async.notify_finished(@exit_status)
|
46
67
|
end
|
47
68
|
|
48
|
-
def start_async_deploy
|
69
|
+
def start_async_deploy
|
49
70
|
RightScale::RightPopen.popen3_async(
|
50
|
-
cmd,
|
71
|
+
@cmd,
|
51
72
|
target: self,
|
52
|
-
environment: options
|
73
|
+
environment: @options.fetch(:environment, nil),
|
53
74
|
pid_handler: :on_pid,
|
54
75
|
input: :on_input_stdin,
|
55
76
|
stdout_handler: :on_read_stdout,
|
@@ -78,6 +99,7 @@ module CapistranoMulticonfigParallel
|
|
78
99
|
def on_exit(status)
|
79
100
|
log_to_file "Child process for worker #{@job_id} on_exit disconnected due to error #{status.inspect}"
|
80
101
|
@exit_status = status.exitstatus
|
102
|
+
check_exit_status
|
81
103
|
end
|
82
104
|
|
83
105
|
def async_exception_handler(*data)
|
@@ -1,15 +1,14 @@
|
|
1
1
|
require_relative '../helpers/application_helper'
|
2
2
|
module CapistranoMulticonfigParallel
|
3
3
|
# class that handles the rake task and waits for approval from the celluloid worker
|
4
|
-
# rubocop:disable ClassLength
|
5
4
|
class RakeWorker
|
6
5
|
include Celluloid
|
7
6
|
include Celluloid::Logger
|
8
7
|
include CapistranoMulticonfigParallel::ApplicationHelper
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
attr_reader :env, :client, :job_id, :action, :task,
|
10
|
+
:task_approved, :successfull_subscription,
|
11
|
+
:subscription_channel, :publisher_channel, :stdin_result
|
13
12
|
|
14
13
|
def work(env, options = {})
|
15
14
|
@options = options.stringify_keys
|
@@ -73,32 +72,21 @@ module CapistranoMulticonfigParallel
|
|
73
72
|
|
74
73
|
def on_message(message)
|
75
74
|
return unless message.present?
|
76
|
-
|
75
|
+
log_to_file("Rake worker #{@job_id} received after on message:", message)
|
77
76
|
if @client.succesfull_subscription?(message)
|
78
77
|
publish_subscription_successfull(message)
|
79
|
-
elsif msg_for_task?(message)
|
78
|
+
elsif msg_for_task?(message)
|
80
79
|
task_approval(message)
|
80
|
+
elsif msg_for_stdin?(message)
|
81
81
|
stdin_approval(message)
|
82
82
|
else
|
83
83
|
show_warning "unknown action: #{message.inspect}"
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
def log_debug(action, message)
|
88
|
-
log_to_file("Rake worker #{@job_id} received after #{action}: #{message}")
|
89
|
-
end
|
90
|
-
|
91
|
-
def msg_for_stdin?(message)
|
92
|
-
message['action'] == 'stdin'
|
93
|
-
end
|
94
|
-
|
95
|
-
def msg_for_task?(message)
|
96
|
-
message['task'].present?
|
97
|
-
end
|
98
|
-
|
99
87
|
def publish_subscription_successfull(message)
|
100
88
|
return unless @client.succesfull_subscription?(message)
|
101
|
-
|
89
|
+
log_to_file("Rake worker #{@job_id} received after publish_subscription_successfull:", message)
|
102
90
|
@successfull_subscription = true
|
103
91
|
publish_to_worker(task_data)
|
104
92
|
end
|
@@ -106,14 +94,14 @@ module CapistranoMulticonfigParallel
|
|
106
94
|
def wait_for_stdin_input
|
107
95
|
wait_execution until @stdin_result.present?
|
108
96
|
output = @stdin_result.clone
|
109
|
-
|
97
|
+
@stdin_result = nil
|
110
98
|
output
|
111
99
|
end
|
112
100
|
|
113
101
|
def stdin_approval(message)
|
114
102
|
return unless msg_for_stdin?(message)
|
115
|
-
if @job_id
|
116
|
-
@stdin_result = message
|
103
|
+
if @job_id == message['job_id']
|
104
|
+
@stdin_result = message.fetch('result', '')
|
117
105
|
else
|
118
106
|
show_warning "unknown invocation #{message.inspect}"
|
119
107
|
end
|
@@ -121,7 +109,7 @@ module CapistranoMulticonfigParallel
|
|
121
109
|
|
122
110
|
def task_approval(message)
|
123
111
|
return unless msg_for_task?(message)
|
124
|
-
if @job_id
|
112
|
+
if @job_id == message['job_id'] && message['task'] == task_name && message['approved'] == 'yes'
|
125
113
|
@task_approved = true
|
126
114
|
else
|
127
115
|
show_warning "unknown invocation #{message.inspect}"
|
@@ -133,27 +121,11 @@ module CapistranoMulticonfigParallel
|
|
133
121
|
terminate
|
134
122
|
end
|
135
123
|
|
136
|
-
def get_question_details(data)
|
137
|
-
question = ''
|
138
|
-
default = nil
|
139
|
-
if data =~ /(.*)\?*\s*\:*\s*(\([^)]*\))*/m
|
140
|
-
question = Regexp.last_match(1)
|
141
|
-
default = Regexp.last_match(2)
|
142
|
-
end
|
143
|
-
question.present? ? [question, default] : nil
|
144
|
-
end
|
145
|
-
|
146
|
-
def printing_question?(data)
|
147
|
-
get_question_details(data).present?
|
148
|
-
end
|
149
|
-
|
150
124
|
def user_prompt_needed?(data)
|
151
|
-
|
152
|
-
|
153
|
-
details = get_question_details(data)
|
154
|
-
default = details.second.present? ? details.second : nil
|
125
|
+
question, default = get_question_details(data)
|
126
|
+
return if question.blank? || @action != 'invoke'
|
155
127
|
publish_to_worker(action: 'stdout',
|
156
|
-
question:
|
128
|
+
question: question,
|
157
129
|
default: default.delete('()'),
|
158
130
|
job_id: @job_id)
|
159
131
|
wait_for_stdin_input
|
@@ -28,10 +28,9 @@ module CapistranoMulticonfigParallel
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def notify_time_change(_channel, _message)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
display_table_on_terminal
|
31
|
+
table = Terminal::Table.new(title: 'Deployment Status Table', headings: default_heaadings)
|
32
|
+
setup_table_jobs(table)
|
33
|
+
display_table_on_terminal(table)
|
35
34
|
end
|
36
35
|
|
37
36
|
def rescue_exception(ex)
|
@@ -40,16 +39,17 @@ module CapistranoMulticonfigParallel
|
|
40
39
|
terminate
|
41
40
|
end
|
42
41
|
|
43
|
-
def display_table_on_terminal
|
42
|
+
def display_table_on_terminal(table)
|
44
43
|
terminal_clear
|
45
|
-
puts "\n#{
|
44
|
+
puts "\n#{table}\n"
|
46
45
|
signal_complete
|
47
46
|
end
|
48
47
|
|
49
|
-
def setup_table_jobs(
|
50
|
-
jobs.
|
51
|
-
|
52
|
-
|
48
|
+
def setup_table_jobs(table)
|
49
|
+
jobs = @manager.alive? ? @manager.jobs.dup : []
|
50
|
+
jobs.each do |_job_id, job|
|
51
|
+
table.add_row(job.terminal_row)
|
52
|
+
table.add_separator
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -59,9 +59,16 @@ module CapistranoMulticonfigParallel
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
def managers_alive?
|
63
|
+
@job_manager.alive? && @manager.alive?
|
64
|
+
end
|
65
|
+
|
62
66
|
def signal_complete
|
63
|
-
|
64
|
-
|
67
|
+
if managers_alive? && @manager.all_workers_finished?
|
68
|
+
@job_manager.condition.signal('completed')
|
69
|
+
elsif !managers_alive?
|
70
|
+
terminate
|
71
|
+
end
|
65
72
|
end
|
66
73
|
|
67
74
|
def terminal_clear
|
@@ -5,7 +5,7 @@ module CapistranoMulticonfigParallel
|
|
5
5
|
class Job
|
6
6
|
include CapistranoMulticonfigParallel::ApplicationHelper
|
7
7
|
|
8
|
-
attr_reader :options
|
8
|
+
attr_reader :options
|
9
9
|
attr_writer :status, :exit_status
|
10
10
|
|
11
11
|
delegate :job_stage,
|
@@ -16,7 +16,7 @@ module CapistranoMulticonfigParallel
|
|
16
16
|
to: :command
|
17
17
|
|
18
18
|
def initialize(application, options)
|
19
|
-
@options = options
|
19
|
+
@options = options.stringify_keys
|
20
20
|
@application = application
|
21
21
|
@manager = @application.manager
|
22
22
|
end
|
@@ -33,9 +33,9 @@ module CapistranoMulticonfigParallel
|
|
33
33
|
setup_command_line(filtered_keys: [env_variable])
|
34
34
|
end
|
35
35
|
|
36
|
-
def terminal_row
|
36
|
+
def terminal_row
|
37
37
|
[
|
38
|
-
{ value:
|
38
|
+
{ value: count.to_s },
|
39
39
|
{ value: id.to_s },
|
40
40
|
{ value: wrap_string(job_stage) },
|
41
41
|
{ value: wrap_string(capistrano_action) },
|
@@ -51,43 +51,26 @@ module CapistranoMulticonfigParallel
|
|
51
51
|
worker.alive? ? worker.worker_state : default
|
52
52
|
end
|
53
53
|
|
54
|
-
def job_writer_attributes
|
55
|
-
%w(status exit_status)
|
56
|
-
end
|
57
|
-
|
58
|
-
def setup_writer_attributes(options)
|
59
|
-
job_writer_attributes.each do |attribute|
|
60
|
-
send("#{attribute}=", options.fetch("#{attribute}", send(attribute)))
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
54
|
def id
|
65
55
|
@id ||= @options.fetch('id', SecureRandom.uuid)
|
66
56
|
end
|
67
57
|
|
68
|
-
def status
|
69
|
-
@status ||= @options.fetch('status', :unstarted)
|
70
|
-
end
|
71
|
-
|
72
|
-
def exit_status
|
73
|
-
@exit_status ||= @options.fetch('exit_status', nil)
|
74
|
-
end
|
75
|
-
|
76
58
|
[
|
77
59
|
{ name: 'app', default: '' },
|
78
60
|
{ name: 'stage', default: '' },
|
79
61
|
{ name: 'action', default: '' },
|
80
62
|
{ name: 'task_arguments', default: [] },
|
81
|
-
{ name: 'env_options', default: {} }
|
63
|
+
{ name: 'env_options', default: {} },
|
64
|
+
{ name: 'status', default: :unstarted },
|
65
|
+
{ name: 'exit_status', default: nil },
|
66
|
+
{ name: 'count', default: nil }
|
82
67
|
].each do |hash|
|
83
68
|
define_method hash[:name] do
|
84
69
|
value = @options.fetch(hash[:name], hash[:default])
|
85
70
|
value["#{env_variable}"] = id if hash[:name] == 'env_options'
|
86
|
-
verify_empty_options(value)
|
71
|
+
value = verify_empty_options(value)
|
72
|
+
instance_variable_set("@#{hash[:name]}", instance_variable_get("@#{hash[:name]}") || value)
|
87
73
|
end
|
88
|
-
# define_method "#{hash[:name]}=" do |value|
|
89
|
-
# self.send("#{hash[:name]}=", value)
|
90
|
-
# end
|
91
74
|
end
|
92
75
|
|
93
76
|
def finished?
|
@@ -14,6 +14,19 @@ module CapistranoMulticonfigParallel
|
|
14
14
|
|
15
15
|
module_function
|
16
16
|
|
17
|
+
def msg_for_stdin?(message)
|
18
|
+
message['action'] == 'stdin'
|
19
|
+
end
|
20
|
+
|
21
|
+
def msg_for_task?(message)
|
22
|
+
message['task'].present?
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_question_details(data)
|
26
|
+
/(.*)\?*\s*\:*\s*(\([^)]*\))*/m =~ data
|
27
|
+
[regex_last_match(1), regex_last_match(2)]
|
28
|
+
end
|
29
|
+
|
17
30
|
def setup_command_line_standard(*args)
|
18
31
|
options = args.extract_options!
|
19
32
|
args.select(&:present?)
|
@@ -38,12 +38,8 @@ module CapistranoMulticonfigParallel
|
|
38
38
|
result
|
39
39
|
end
|
40
40
|
|
41
|
-
def filtered_errors
|
42
|
-
[CapistranoMulticonfigParallel::CelluloidWorker::TaskFailed, Celluloid::DeadActorError, Celluloid::Task::TerminatedError]
|
43
|
-
end
|
44
|
-
|
45
41
|
def error_filtered?(error)
|
46
|
-
|
42
|
+
[CapistranoMulticonfigParallel::CelluloidWorker::TaskFailed].find { |class_name| error.is_a?(class_name) }.present?
|
47
43
|
end
|
48
44
|
|
49
45
|
def log_error(error, output = nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano_multiconfig_parallel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bogdanRada
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: celluloid-pmap
|