3b4af59a5f
This changes ProjectCacheWorker.perform_async so it only schedules a job when no lease for the given project is present. This ensures we don't end up scheduling hundreds of jobs when they won't be executed anyway.
54 lines
1.4 KiB
Ruby
54 lines
1.4 KiB
Ruby
# Worker for updating any project specific caches.
|
|
#
|
|
# This worker runs at most once every 15 minutes per project. This is to ensure
|
|
# that multiple instances of jobs for this worker don't hammer the underlying
|
|
# storage engine as much.
|
|
class ProjectCacheWorker
|
|
include Sidekiq::Worker
|
|
include DedicatedSidekiqQueue
|
|
|
|
LEASE_TIMEOUT = 15.minutes.to_i
|
|
|
|
def self.lease_for(project_id)
|
|
Gitlab::ExclusiveLease.
|
|
new("project_cache_worker:#{project_id}", timeout: LEASE_TIMEOUT)
|
|
end
|
|
|
|
# Overwrite Sidekiq's implementation so we only schedule when actually needed.
|
|
def self.perform_async(project_id)
|
|
# If a lease for this project is still being held there's no point in
|
|
# scheduling a new job.
|
|
super unless lease_for(project_id).exists?
|
|
end
|
|
|
|
def perform(project_id)
|
|
if try_obtain_lease_for(project_id)
|
|
Rails.logger.
|
|
info("Obtained ProjectCacheWorker lease for project #{project_id}")
|
|
else
|
|
Rails.logger.
|
|
info("Could not obtain ProjectCacheWorker lease for project #{project_id}")
|
|
|
|
return
|
|
end
|
|
|
|
update_caches(project_id)
|
|
end
|
|
|
|
def update_caches(project_id)
|
|
project = Project.find(project_id)
|
|
|
|
return unless project.repository.exists?
|
|
|
|
project.update_repository_size
|
|
project.update_commit_count
|
|
|
|
if project.repository.root_ref
|
|
project.repository.build_cache
|
|
end
|
|
end
|
|
|
|
def try_obtain_lease_for(project_id)
|
|
self.class.lease_for(project_id).try_obtain
|
|
end
|
|
end
|