Skip to content

Commit

Permalink
Skip interim web processes from SUPERSEDED (CANCELED) deployments
Browse files Browse the repository at this point in the history
When a deployment train is canceled, the latest interim web process is
scaled up. The introduction of a SUPERSEDED (CANCELED) state requires a
change to how this latest interim web process is determined.

Let's assume the following combination of actions:
  create + create + cancel + create + cancel

This would result in three deployments with the following states:
  SUPERSEDED (DEPLOYED) + SUPERSEDED (CANCELED) + CANCELING

And this should result in the web process from the SUPERSEDED (DEPLOYED)
deployment to be scaled up.
  • Loading branch information
philippthun committed Nov 28, 2022
1 parent d1dd3e7 commit 7f15557
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 14 deletions.
19 changes: 10 additions & 9 deletions lib/cloud_controller/deployment_updater/updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ def cancel_deployment

deploying_web_process.lock!

prior_web_process = web_processes.
reject { |p| p.guid == deploying_web_process.guid }.
max_by(&:created_at)
# Find newest interim web process belonging to a SUPERSEDED (DEPLOYED) deployment.
interim_web_process = app.web_processes_dataset.qualify.
join(:deployments, deploying_web_process_guid: :guid).
where(deployments__state: DeploymentModel::DEPLOYED_STATE).
where(deployments__status_reason: DeploymentModel::SUPERSEDED_STATUS_REASON).
order(Sequel.desc(:created_at), Sequel.desc(:id)).
first
prior_web_process = interim_web_process || app.oldest_web_process
prior_web_process.lock!

prior_web_process.update(instances: deployment.original_web_process_instance_count, type: ProcessTypes::WEB)
Expand Down Expand Up @@ -97,11 +102,7 @@ def deploying_web_process
end

def oldest_web_process_with_instances
@oldest_web_process_with_instances ||= app.processes.select { |process| process.web? && process.instances > 0 }.min_by(&:created_at)
end

def web_processes
app.processes.select(&:web?)
@oldest_web_process_with_instances ||= app.web_processes.select { |process| process.instances > 0 }.min_by(&:created_at)
end

def is_original_web_process?(process)
Expand Down Expand Up @@ -142,7 +143,7 @@ def promote_deploying_web_process
end

def cleanup_web_processes_except(protected_process)
web_processes.
app.web_processes.
reject { |p| p.guid == protected_process.guid }.
map(&:destroy)
end
Expand Down
40 changes: 35 additions & 5 deletions spec/unit/lib/cloud_controller/deployment_updater/updater_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -483,22 +483,28 @@ module VCAP::CloudController
end

context 'when there are interim deployments' do
let!(:interim_deploying_web_process) {
let!(:interim_deploying_web_process) do
ProcessModel.make(
app: app,
created_at: an_hour_ago,
type: ProcessTypes::WEB,
instances: 1,
guid: 'guid-interim'
)
}

let!(:interim_route_mapping) {
end
let!(:interim_deployed_superseded_deployment) do
DeploymentModel.make(
deploying_web_process: interim_deploying_web_process,
state: 'DEPLOYED',
status_reason: 'SUPERSEDED'
)
end
let!(:interim_route_mapping) do
RouteMappingModel.make(
app: web_process.app,
process_type: interim_deploying_web_process.type
)
}
end

it 'it scales up the most recent interim web process' do
subject.cancel
Expand All @@ -510,6 +516,30 @@ module VCAP::CloudController
subject.cancel
expect(app.reload.processes.map(&:guid)).to eq([interim_deploying_web_process.guid])
end

context 'when there is an interim deployment that has been SUPERSEDED (CANCELED)' do
let!(:interim_canceling_web_process) do
ProcessModel.make(
app: app,
created_at: an_hour_ago + 1,
type: ProcessTypes::WEB,
instances: 1,
guid: 'guid-canceling'
)
end
let!(:interim_canceled_superseded_deployment) do
DeploymentModel.make(
deploying_web_process: interim_canceling_web_process,
state: 'CANCELED',
status_reason: 'SUPERSEDED'
)
end

it 'sets the most recent interim web process belonging to a SUPERSEDED (DEPLOYED) deployment as the only web process' do
subject.cancel
expect(app.reload.processes.map(&:guid)).to eq([interim_deploying_web_process.guid])
end
end
end

context 'deployment got superseded' do
Expand Down

0 comments on commit 7f15557

Please sign in to comment.