diff options
Diffstat (limited to 'app/workers/repository_check')
-rw-r--r-- | app/workers/repository_check/batch_worker.rb | 35 | ||||
-rw-r--r-- | app/workers/repository_check/single_repository_worker.rb | 48 |
2 files changed, 50 insertions, 33 deletions
diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb index 76688cf51c1..72f0a9b0619 100644 --- a/app/workers/repository_check/batch_worker.rb +++ b/app/workers/repository_check/batch_worker.rb @@ -4,8 +4,11 @@ module RepositoryCheck include CronjobQueue RUN_TIME = 3600 + BATCH_SIZE = 10_000 def perform + return unless Gitlab::CurrentSettings.repository_checks_enabled + start = Time.now # This loop will break after a little more than one hour ('a little @@ -15,7 +18,6 @@ module RepositoryCheck # check, only one (or two) will be checked at a time. project_ids.each do |project_id| break if Time.now - start >= RUN_TIME - break unless current_settings.repository_checks_enabled next unless try_obtain_lease(project_id) @@ -31,12 +33,20 @@ module RepositoryCheck # getting ID's from Postgres is not terribly slow, and because no user # has to sit and wait for this query to finish. def project_ids - limit = 10_000 - never_checked_projects = Project.where('last_repository_check_at IS NULL AND created_at < ?', 24.hours.ago) - .limit(limit).pluck(:id) - old_check_projects = Project.where('last_repository_check_at < ?', 1.month.ago) - .reorder('last_repository_check_at ASC').limit(limit).pluck(:id) - never_checked_projects + old_check_projects + never_checked_project_ids(BATCH_SIZE) + old_checked_project_ids(BATCH_SIZE) + end + + def never_checked_project_ids(batch_size) + Project.where(last_repository_check_at: nil) + .where('created_at < ?', 24.hours.ago) + .limit(batch_size).pluck(:id) + end + + def old_checked_project_ids(batch_size) + Project.where.not(last_repository_check_at: nil) + .where('last_repository_check_at < ?', 1.month.ago) + .reorder(last_repository_check_at: :asc) + .limit(batch_size).pluck(:id) end def try_obtain_lease(id) @@ -47,16 +57,5 @@ module RepositoryCheck timeout: 24.hours ).try_obtain end - - def current_settings - # No caching of the settings! If we cache them and an admin disables - # this feature, an active RepositoryCheckWorker would keep going for up - # to 1 hour after the feature was disabled. - if Rails.env.test? - Gitlab::CurrentSettings.fake_application_settings - else - ApplicationSetting.current - end - end end end diff --git a/app/workers/repository_check/single_repository_worker.rb b/app/workers/repository_check/single_repository_worker.rb index 116bc185b38..3cffb8b14e4 100644 --- a/app/workers/repository_check/single_repository_worker.rb +++ b/app/workers/repository_check/single_repository_worker.rb @@ -5,27 +5,34 @@ module RepositoryCheck def perform(project_id) project = Project.find(project_id) + healthy = project_healthy?(project) + + update_repository_check_status(project, healthy) + end + + private + + def update_repository_check_status(project, healthy) project.update_columns( - last_repository_check_failed: !check(project), + last_repository_check_failed: !healthy, last_repository_check_at: Time.now ) end - private + def project_healthy?(project) + repo_healthy?(project) && wiki_repo_healthy?(project) + end - def check(project) - if has_pushes?(project) && !git_fsck(project.repository) - false - elsif project.wiki_enabled? - # Historically some projects never had their wiki repos initialized; - # this happens on project creation now. Let's initialize an empty repo - # if it is not already there. - project.create_wiki + def repo_healthy?(project) + return true unless has_changes?(project) - git_fsck(project.wiki.repository) - else - true - end + git_fsck(project.repository) + end + + def wiki_repo_healthy?(project) + return true unless has_wiki_changes?(project) + + git_fsck(project.wiki.repository) end def git_fsck(repository) @@ -39,8 +46,19 @@ module RepositoryCheck false end - def has_pushes?(project) + def has_changes?(project) Project.with_push.exists?(project.id) end + + def has_wiki_changes?(project) + return false unless project.wiki_enabled? + + # Historically some projects never had their wiki repos initialized; + # this happens on project creation now. Let's initialize an empty repo + # if it is not already there. + return false unless project.create_wiki + + has_changes?(project) + end end end |