diff --git a/modules/storages/app/models/storages/storage.rb b/modules/storages/app/models/storages/storage.rb index 2e4a06eeda75..07e02e575ab6 100644 --- a/modules/storages/app/models/storages/storage.rb +++ b/modules/storages/app/models/storages/storage.rb @@ -83,6 +83,8 @@ class Storage < ApplicationRecord scope :automatic_management_enabled, -> { where("provider_fields->>'automatically_managed' = 'true'") } + scope :in_project, ->(project_id) { joins(project_storages: :project).where(project_storages: { project_id: }) } + enum health_status: { pending: "pending", healthy: "healthy", diff --git a/modules/storages/app/workers/storages/automatically_managed_storage_sync_job.rb b/modules/storages/app/workers/storages/automatically_managed_storage_sync_job.rb index 2543bebfd075..83ceca6c4841 100644 --- a/modules/storages/app/workers/storages/automatically_managed_storage_sync_job.rb +++ b/modules/storages/app/workers/storages/automatically_managed_storage_sync_job.rb @@ -1,23 +1,14 @@ +# frozen_string_literal: true + #-- copyright #++ module Storages class AutomaticallyManagedStorageSyncJob < ApplicationJob include GoodJob::ActiveJobExtensions::Concurrency + queue_with_priority :above_normal SINGLE_THREAD_DEBOUNCE_TIME = 4.seconds - class << self - def debounce(storage) - key = "sync-#{storage.short_provider_type}-#{storage.id}" - timestamp = RequestStore.store[key] - - return false if timestamp.present? && (timestamp + SINGLE_THREAD_DEBOUNCE_TIME) > Time.current - - result = set(wait: 5.seconds).perform_later(storage) - RequestStore.store[key] = Time.current - result - end - end good_job_control_concurrency_with( total_limit: 2, @@ -36,6 +27,19 @@ def debounce(storage) end end + class << self + def debounce(storage) + key = "sync-#{storage.short_provider_type}-#{storage.id}" + timestamp = RequestStore.store[key] + + return false if timestamp.present? && (timestamp + SINGLE_THREAD_DEBOUNCE_TIME) > Time.current + + result = set(wait: 5.seconds).perform_later(storage) + RequestStore.store[key] = Time.current + result + end + end + def perform(storage) return unless storage.configured? && storage.automatically_managed? diff --git a/modules/storages/lib/open_project/storages/engine.rb b/modules/storages/lib/open_project/storages/engine.rb index 134195f6de52..32a7c8b60a33 100644 --- a/modules/storages/lib/open_project/storages/engine.rb +++ b/modules/storages/lib/open_project/storages/engine.rb @@ -58,8 +58,7 @@ def self.permissions OpenProject::Events::MEMBER_DESTROYED ].each do |event| OpenProject::Notifications.subscribe(event) do |payload| - ::Storages::Storage.joins(project_storages: :project) - .where(project_storages: { project_id: payload[:member].project_id }).find_each do |storage| + ::Storages::Storage.in_project(payload[:member].project_id).find_each do |storage| ::Storages::AutomaticallyManagedStorageSyncJob.debounce(storage) end end @@ -70,8 +69,7 @@ def self.permissions OpenProject::Events::PROJECT_ARCHIVED, OpenProject::Events::PROJECT_UNARCHIVED].each do |event| OpenProject::Notifications.subscribe(event) do |payload| - ::Storages::Storage.joins(project_storages: :project) - .where(project_storages: { project: payload[:project] }).find_each do |storage| + ::Storages::Storage.in_project(payload[:project].id).find_each do |storage| ::Storages::AutomaticallyManagedStorageSyncJob.debounce(storage) end end