From 6f9adba1c9dd2bd97e03b0cabb8e6afd1962e236 Mon Sep 17 00:00:00 2001 From: Thibaud Guillaume-Gentil Date: Sat, 16 Nov 2024 17:12:06 +0100 Subject: [PATCH] Tenant job context fine-tuning --- Gemfile.lock | 12 +++++----- app/jobs/application_job.rb | 6 ++--- .../{tenant_switcher.rb => tenant_context.rb} | 24 ++++++++++--------- .../initializers/action_mailer_job_tenant.rb | 2 +- .../initializers/active_storage_job_tenant.rb | 2 +- lib/tenant.rb | 2 +- ...witcher_spec.rb => tenant_context_spec.rb} | 6 ++--- 7 files changed, 28 insertions(+), 26 deletions(-) rename app/jobs/concerns/{tenant_switcher.rb => tenant_context.rb} (77%) rename spec/jobs/concerns/{tenant_switcher_spec.rb => tenant_context_spec.rb} (96%) diff --git a/Gemfile.lock b/Gemfile.lock index 8445f83d..c8c99dcd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -305,7 +305,7 @@ GEM mini_mime (1.1.5) mini_portile2 (2.8.8) minitest (5.25.1) - mission_control-jobs (0.5.0) + mission_control-jobs (0.6.0) actioncable (>= 7.1) actionpack (>= 7.1) activejob (>= 7.1) @@ -539,7 +539,7 @@ GEM slim (5.2.1) temple (~> 0.10.0) tilt (>= 2.1.0) - solid_queue (1.0.1) + solid_queue (1.0.2) activejob (>= 7.1) activerecord (>= 7.1) concurrent-ruby (>= 1.3.1) @@ -554,16 +554,16 @@ GEM stimulus-rails (1.3.4) railties (>= 6.0.0) stringio (3.1.2) - super_diff (0.13.0) + super_diff (0.14.0) attr_extras (>= 6.2.4) diff-lcs patience_diff tailwindcss-rails (3.0.0) railties (>= 7.0.0) tailwindcss-ruby - tailwindcss-ruby (3.4.14) - tailwindcss-ruby (3.4.14-arm64-darwin) - tailwindcss-ruby (3.4.14-x86_64-linux) + tailwindcss-ruby (3.4.15) + tailwindcss-ruby (3.4.15-arm64-darwin) + tailwindcss-ruby (3.4.15-x86_64-linux) temple (0.10.3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 4cf9546b..f5508360 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true class ApplicationJob < ActiveJob::Base - include TenantSwitcher + include TenantContext # Automatically retry jobs that encountered a deadlock - # retry_on ActiveRecord::Deadlocked + retry_on ActiveRecord::Deadlocked # Most jobs are safe to ignore if the underlying records are no longer available - # discard_on ActiveJob::DeserializationError + discard_on ActiveJob::DeserializationError end diff --git a/app/jobs/concerns/tenant_switcher.rb b/app/jobs/concerns/tenant_context.rb similarity index 77% rename from app/jobs/concerns/tenant_switcher.rb rename to app/jobs/concerns/tenant_context.rb index 4a87fc41..7c70a9c2 100644 --- a/app/jobs/concerns/tenant_switcher.rb +++ b/app/jobs/concerns/tenant_context.rb @@ -1,18 +1,11 @@ # frozen_string_literal: true -module TenantSwitcher +module TenantContext extend ActiveSupport::Concern included do around_perform do |job, block| - begin - context = job.arguments.pop - Tenant.switch(context["tenant"]) do - Current.set(context["current"], &block) - end - ensure - job.set_context(context) - end + job.with_context(&block) end end @@ -24,14 +17,23 @@ def serialize super end + def with_context(&block) + context = arguments.pop + Tenant.switch(context["tenant"]) do + Current.set(context["current"], &block) + end + ensure + set_context(context) + end + + private + def set_context(context) return if context_set?(context) self.arguments << context end - private - def context_set?(context) last_argument = self.arguments&.last return unless last_argument.is_a?(Hash) diff --git a/config/initializers/action_mailer_job_tenant.rb b/config/initializers/action_mailer_job_tenant.rb index 6c1c422b..e9eb91a0 100644 --- a/config/initializers/action_mailer_job_tenant.rb +++ b/config/initializers/action_mailer_job_tenant.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true Rails.application.config.after_initialize do - ActionMailer::MailDeliveryJob.include(TenantSwitcher) + ActionMailer::MailDeliveryJob.include(TenantContext) end diff --git a/config/initializers/active_storage_job_tenant.rb b/config/initializers/active_storage_job_tenant.rb index dd1377b4..790d835c 100644 --- a/config/initializers/active_storage_job_tenant.rb +++ b/config/initializers/active_storage_job_tenant.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true Rails.application.config.after_initialize do - ActiveStorage::BaseJob.include(TenantSwitcher) + ActiveStorage::BaseJob.include(TenantContext) end diff --git a/lib/tenant.rb b/lib/tenant.rb index fe4ab213..433b1b67 100644 --- a/lib/tenant.rb +++ b/lib/tenant.rb @@ -72,8 +72,8 @@ def disconnect private def enter(tenant) - return if tenant == current raise "Unknown tenant '#{tenant}'" unless exists?(tenant) + return if tenant == current raise "Illegal tenant switch (#{current} => #{tenant})" unless outside? self.current = tenant diff --git a/spec/jobs/concerns/tenant_switcher_spec.rb b/spec/jobs/concerns/tenant_context_spec.rb similarity index 96% rename from spec/jobs/concerns/tenant_switcher_spec.rb rename to spec/jobs/concerns/tenant_context_spec.rb index b0573bc3..f533cdb7 100644 --- a/spec/jobs/concerns/tenant_switcher_spec.rb +++ b/spec/jobs/concerns/tenant_context_spec.rb @@ -1,9 +1,9 @@ require "rails_helper" -describe TenantSwitcher do +describe TenantContext do specify "add current attributes and tenant last arguments" do class DummyJob < ActiveJob::Base - include TenantSwitcher + include TenantContext def perform(admin, name: nil) admin.update!(name: name) end @@ -31,7 +31,7 @@ def perform(admin, name: nil) specify "retry with the same current attributes and tenant last arguments" do class DummyExceptionJob < ActiveJob::Base - include TenantSwitcher + include TenantContext retry_on Exception, wait: :polynomially_longer, attempts: 2 def perform(foo)