Skip to content

Commit 55ab2a2

Browse files
committed
Fix ProcessObserver to use DB-assigned updated_at timestamps
Reload the process model before passing it to the runner in ProcessObserver#react_to_state_change and #react_to_instances_change. Without the reload, the in-memory updated_at value is stale (set before the DB update). ProcessesSync compares this timestamp against the LRP annotation to detect drift, causing unnecessary re-syncs when the values don't match.
1 parent 36b3697 commit 55ab2a2

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

lib/cloud_controller/process_observer.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,15 @@ def react_to_state_change(process)
3737

3838
process.update(revision: process.app.latest_revision) if process.revisions_enabled?
3939

40-
@runners.runner_for_process(process).start unless process.needs_staging?
40+
# Reload to get the DB-assigned updated_at, which ProcessesSync compares against
41+
# the LRP annotation to detect drift. Without this, the stale in-memory value
42+
# causes an unnecessary re-sync.
43+
@runners.runner_for_process(process.reload).start unless process.needs_staging?
4144
end
4245

4346
def react_to_instances_change(process)
44-
@runners.runner_for_process(process).scale if process.started? && process.active?
47+
# Same as above: reload to get the DB-assigned updated_at before building the LRP annotation.
48+
@runners.runner_for_process(process.reload).scale if process.started? && process.active?
4549
end
4650

4751
def with_diego_communication_handling

spec/unit/lib/cloud_controller/process_observer_spec.rb

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module VCAP::CloudController
55
let(:stagers) { double(:stagers, stager_for_build: stager) }
66
let(:runners) { instance_double(Runners, runner_for_process: runner) }
77
let(:stager) { double(:stager) }
8-
let(:runner) { instance_double(Diego::Runner, stop: nil, start: nil) }
8+
let(:runner) { instance_double(Diego::Runner, stop: nil, start: nil, scale: nil) }
99
let(:process_active) { true }
1010
let(:diego) { false }
1111
let(:process) do
@@ -33,6 +33,7 @@ module VCAP::CloudController
3333

3434
before do
3535
ProcessObserver.configure(stagers, runners)
36+
allow(process).to receive(:reload).and_return(process)
3637
end
3738

3839
describe '.deleted' do
@@ -312,6 +313,35 @@ module VCAP::CloudController
312313
end
313314
end
314315
end
316+
317+
context 'updated_at annotation accuracy' do
318+
let(:received) { [] }
319+
320+
before do
321+
allow(runners).to receive(:runner_for_process) do |p|
322+
received << p.updated_at
323+
runner
324+
end
325+
end
326+
327+
context 'when the process instances have changed' do
328+
it 'passes a process with the correct updated_at timestamp to the runner', isolation: :truncation do
329+
process_model = ProcessModelFactory.make(state: 'STARTED')
330+
process_model.update(instances: process_model.instances + 1)
331+
332+
expect(received.last).to eq(process_model.reload.updated_at)
333+
end
334+
end
335+
336+
context 'when the process state has changed' do
337+
it 'passes a process with the correct updated_at timestamp to the runner', isolation: :truncation do
338+
process_model = ProcessModelFactory.make(state: 'STOPPED')
339+
process_model.update(state: ProcessModel::STARTED)
340+
341+
expect(received.last).to eq(process_model.reload.updated_at)
342+
end
343+
end
344+
end
315345
end
316346
end
317347
end

spec/unit/models/runtime/process_model_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,7 @@ def act_as_cf_admin
14951495
end
14961496

14971497
describe 'saving' do
1498-
it 'calls AppObserver.updated', isolation: :truncation do
1498+
it 'calls ProcessObserver.updated', isolation: :truncation do
14991499
process = ProcessModelFactory.make
15001500
expect(ProcessObserver).to receive(:updated).with(process)
15011501
process.update(instances: process.instances + 1)

0 commit comments

Comments
 (0)