From 3811973ac5df24f9662dad123c4a8f5824377657 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 17 Nov 2017 15:02:48 -0800 Subject: [PATCH] Cap the Geo retry_at value to prevent out of range timestamps Part of #4083 --- app/services/geo/base_sync_service.rb | 11 ++++++++++- .../geo/repository_sync_service_spec.rb | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/services/geo/base_sync_service.rb b/app/services/geo/base_sync_service.rb index 0f926f0af4384..1a8eb55909dc5 100644 --- a/app/services/geo/base_sync_service.rb +++ b/app/services/geo/base_sync_service.rb @@ -136,7 +136,7 @@ def update_registry(started_at: nil, finished_at: nil) if started_at attrs["last_#{type}_synced_at"] = started_at attrs["#{type}_retry_count"] = retry_count + 1 - attrs["#{type}_retry_at"] = Time.now + delay(attrs["#{type}_retry_count"]).seconds + attrs["#{type}_retry_at"] = next_retry_time(attrs["#{type}_retry_count"]) end if finished_at @@ -210,5 +210,14 @@ def set_temp_repository_as_main raise Gitlab::Shell::Error, 'Can not move temporary repository' end end + + # To prevent the retry time from storing invalid dates in the database, + # cap the max time to a week plus some random jitter value. + def next_retry_time(retry_count) + proposed_time = Time.now + delay(retry_count).seconds + max_future_time = Time.now + 7.days + delay(1).seconds + + [proposed_time, max_future_time].min + end end end diff --git a/spec/services/geo/repository_sync_service_spec.rb b/spec/services/geo/repository_sync_service_spec.rb index 38a8f1ee45a0d..2508308566370 100644 --- a/spec/services/geo/repository_sync_service_spec.rb +++ b/spec/services/geo/repository_sync_service_spec.rb @@ -189,6 +189,25 @@ subject.execute end + + it 'successfully redownloads the file even if the retry time exceeds max value' do + timestamp = Time.now.utc + registry = create( + :geo_project_registry, + project: project, + repository_retry_count: Geo::BaseSyncService::RETRY_BEFORE_REDOWNLOAD + 2000, + repository_retry_at: timestamp, + force_to_redownload_repository: true + ) + + subject.execute + + # The repository should be redownloaded and cleared without errors. If + # the timestamp were not capped, we would have seen a "timestamp out + # of range" in the first update to the project registry. + registry.reload + expect(registry.repository_retry_at).to be_nil + end end context 'secondary replicates over SSH' do -- GitLab