Commit ebf5e945 authored by Tiago Botelho's avatar Tiago Botelho

removes scheduled state transition and updates sync logic

parent d8c7cd86
...@@ -29,16 +29,8 @@ class RemoteMirror < ActiveRecord::Base ...@@ -29,16 +29,8 @@ class RemoteMirror < ActiveRecord::Base
scope :stuck, -> { started.where('last_update_at < ? OR (last_update_at IS NULL AND updated_at < ?)', 1.day.ago, 1.day.ago) } scope :stuck, -> { started.where('last_update_at < ? OR (last_update_at IS NULL AND updated_at < ?)', 1.day.ago, 1.day.ago) }
state_machine :update_status, initial: :none do state_machine :update_status, initial: :none do
event :schedule do
transition [:none, :finished] => :scheduling
end
event :reschedule do
transition failed: :scheduling
end
event :update_start do event :update_start do
transition scheduling: :started transition [:none, :finished, :failed] => :started
end end
event :update_finish do event :update_finish do
...@@ -49,14 +41,11 @@ class RemoteMirror < ActiveRecord::Base ...@@ -49,14 +41,11 @@ class RemoteMirror < ActiveRecord::Base
transition started: :failed transition started: :failed
end end
state :scheduling
state :started state :started
state :finished state :finished
state :failed state :failed
after_transition any => :scheduling, do: :schedule_update_job after_transition any => :started do |remote_mirror, _|
after_transition scheduling: :started do |remote_mirror, _|
remote_mirror.update(last_update_started_at: Time.now) remote_mirror.update(last_update_started_at: Time.now)
end end
...@@ -88,7 +77,7 @@ class RemoteMirror < ActiveRecord::Base ...@@ -88,7 +77,7 @@ class RemoteMirror < ActiveRecord::Base
return unless project return unless project
return if !enabled || update_in_progress? return if !enabled || update_in_progress?
update_failed? ? reschedule : schedule schedule_update_job
end end
def updated_since?(timestamp) def updated_since?(timestamp)
...@@ -146,10 +135,6 @@ class RemoteMirror < ActiveRecord::Base ...@@ -146,10 +135,6 @@ class RemoteMirror < ActiveRecord::Base
end end
def schedule_update_job def schedule_update_job
run_after_commit(:add_update_job)
end
def add_update_job
RepositoryUpdateRemoteMirrorWorker.perform_in(BACKOFF_DELAY, self.id, Time.now) if project&.repository_exists? RepositoryUpdateRemoteMirrorWorker.perform_in(BACKOFF_DELAY, self.id, Time.now) if project&.repository_exists?
end end
......
...@@ -85,6 +85,34 @@ describe RemoteMirror do ...@@ -85,6 +85,34 @@ describe RemoteMirror do
end end
end end
context '#updated_since?' do
let(:remote_mirror) { create(:project, :remote_mirror).remote_mirrors.first }
let(:timestamp) { Time.now - 5.minutes }
before do
Timecop.freeze(Time.now)
remote_mirror.update_attributes(last_update_started_at: Time.now)
end
context 'when remote mirror does not have status failed' do
it 'returns true when last update started after the timestamp' do
expect(remote_mirror.updated_since?(timestamp)).to be true
end
it 'returns false when last update started before the timestamp' do
expect(remote_mirror.updated_since?(Time.now + 5.minutes)).to be false
end
end
context 'when remote mirror has status failed' do
it 'returns false when last update started after the timestamp' do
remote_mirror.update_attributes(update_status: 'failed')
expect(remote_mirror.updated_since?(timestamp)).to be false
end
end
end
context 'no project' do context 'no project' do
it 'includes mirror with a project in pending_delete' do it 'includes mirror with a project in pending_delete' do
mirror = create_mirror(url: 'http://cantbeblank', mirror = create_mirror(url: 'http://cantbeblank',
......
...@@ -4,29 +4,56 @@ describe RepositoryUpdateRemoteMirrorWorker do ...@@ -4,29 +4,56 @@ describe RepositoryUpdateRemoteMirrorWorker do
subject { described_class.new } subject { described_class.new }
let(:remote_mirror) { create(:project, :remote_mirror).remote_mirrors.first } let(:remote_mirror) { create(:project, :remote_mirror).remote_mirrors.first }
let(:scheduled_time) { Time.now - 5.minutes }
before do before do
remote_mirror.update_attributes(update_status: 'started') Timecop.freeze(Time.now)
end end
describe '#perform' do describe '#perform' do
it 'sets sync as finished when update remote mirror service executes successfully' do context 'with status scheduling' do
expect_any_instance_of(Projects::UpdateRemoteMirrorService).to receive(:execute).with(remote_mirror).and_return(status: :success) before do
remote_mirror.update_attributes(update_status: 'none')
end
expect { subject.perform(remote_mirror.id, Time.now) }.to change { remote_mirror.reload.update_status }.to('finished') it 'sets status as finished when update remote mirror service executes successfully' do
end expect_any_instance_of(Projects::UpdateRemoteMirrorService).to receive(:execute).with(remote_mirror).and_return(status: :success)
expect { subject.perform(remote_mirror.id, Time.now) }.to change { remote_mirror.reload.update_status }.to('finished')
end
it 'sets status as failed when update remote mirror service executes with errors' do
expect_any_instance_of(Projects::UpdateRemoteMirrorService).to receive(:execute).with(remote_mirror).and_return(status: :error, message: 'fail!')
expect do
subject.perform(remote_mirror.id, Time.now)
end.to raise_error
expect(remote_mirror.reload.update_status).to eq('failed')
end
it 'sets sync as failed when update remote mirror service executes with errors' do it 'does nothing if last_update_started_at is higher than the time the job was scheduled in' do
expect_any_instance_of(Projects::UpdateRemoteMirrorService).to receive(:execute).with(remote_mirror).and_return(status: :error, message: 'fail!') remote_mirror.update_attributes(last_update_started_at: Time.now)
expect { subject.perform(remote_mirror.id, Time.now) }.to change { remote_mirror.reload.update_status }.to('failed') expect_any_instance_of(RemoteMirror).to receive(:updated_since?).with(scheduled_time).and_return(true)
expect_any_instance_of(Projects::UpdateRemoteMirrorService).not_to receive(:execute).with(remote_mirror)
expect(subject.perform(remote_mirror.id, scheduled_time)).to be_nil
end
end end
it 'does nothing if last_update_at is higher than the time the job was scheduled in' do context 'with status failed' do
expect_any_instance_of(RemoteMirror).to receive(:last_update_at).and_return(Time.now + 10.minutes) before do
expect_any_instance_of(Projects::UpdateRemoteMirrorService).not_to receive(:execute).with(remote_mirror) remote_mirror.update_attributes(update_status: 'failed')
end
it 'sets status as finished if last_update_started_at is higher than the time the job was scheduled in' do
remote_mirror.update_attributes(last_update_started_at: Time.now)
expect_any_instance_of(RemoteMirror).to receive(:updated_since?).with(scheduled_time).and_return(false)
expect_any_instance_of(Projects::UpdateRemoteMirrorService).to receive(:execute).with(remote_mirror).and_return(status: :success)
expect(subject.perform(remote_mirror.id, Time.now)).to be_nil expect { subject.perform(remote_mirror.id, scheduled_time) }.to change { remote_mirror.reload.update_status }.to('finished')
end
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment