apartment-sidekiq: Job running on the wrong tanent

I’m using

gem 'apartment', '~> 2.0'
gem 'apartment-sidekiq', github: 'tmster/apartment-sidekiq'
gem 'sidekiq', '~> 5.0.0'

ruby '2.4.2'
gem 'rails', '5.0.6'
gem 'activerecord-import', '~> 0.20.0'

I got a job that creates a batch of records on the sidekiq dashboard I get this information.

Job BuildFooComponents

Extras {“apartment”=>“other_tanent”}

Error Class

ActiveRecord::RecordNotUnique

Error Message

PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "foo_pkey" DETAIL: Key (id)=(3880) already exists. : INSERT INTO "foo"(column) VALUES (nextval('demo.foo_id_seq')

if you can see the tanent VALUES (nextval('demo.foo_id_seq') is not the same from the extras “apartment”=>“other_tanent”

the job

class BuildFooComponents
  include Sidekiq::Worker
  def perform(components, section_id, project_id)
    group_components=[]
    ...
   FooComponent.import group_components
  end

end

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Reactions: 1
  • Comments: 18

Most upvoted comments

I was able to solve this without this gem. This is the approach:

This is for active jobs (app/jobs/application_job.rb):

class ApplicationJob < ActiveJob::Base
  before_enqueue do |job|
    tenant = Apartment::Tenant.current
    job.arguments.push({}) unless job.arguments.last.is_a?(Hash)
    job.arguments.last.merge!(tenant: tenant)
  end

  before_perform do |job|
    tenant = job.arguments.last[:tenant]
    Apartment::Tenant.switch!(tenant)
  end
end

This is for action mailer config/initializers/mail_delivery_job.rb:

module ActionMailer
  class MailDeliveryJob < ActiveJob::Base
    before_enqueue do |job|
      tenant = Apartment::Tenant.current
      args = job.arguments.last[:args]
      args.push({}) unless args.last.is_a?(Hash)
      args.last.merge!(tenant: tenant)
      job.arguments.last[:args] = args
    end

    before_perform do |job|
      args = job.arguments.last[:args]
      tenant = args.last[:tenant]
      Apartment::Tenant.switch!(tenant)
    end
  end
end

With this you can continue using your jobs and mailers without passing extra params and you get the correct tenant in your jobs.

I hope it is useful for someone.

For my Future Self, for anyone else from $MY_TEAMS coming here, and for everyone else:

If you’re using Rails 5, do not use apartment-sidekiq until it is fixed for Rails 5.

See this blog: http://fuzzyblog.io/blog/rails/2017/08/21/rails-apartment-tenancy-and-sidekiq.html

Your welcome.

You can make it works just by adding checking for the current tenant in the before_perform callback:

before_perform do |job|
  args = job.arguments.last[:args]
  tenant = args.last[:tenant] || Apartment::Tenant.current
  Apartment::Tenant.switch!(tenant)
end

No at the moment, just checking the configurations before starting the test. This is a problem I been trying to fix for some time now. Gracias.

No, I didn’t add anything else. Just your job classes must inherit from ApplicationJob and that’s it. Are you having an issue?

I was able to solve this without this gem. This is the approach:

This is for active jobs (app/jobs/application_job.rb):

class ApplicationJob < ActiveJob::Base
  before_enqueue do |job|
    tenant = Apartment::Tenant.current
    job.arguments.push({}) unless job.arguments.last.is_a?(Hash)
    job.arguments.last.merge!(tenant: tenant)
  end

  before_perform do |job|
    tenant = job.arguments.last[:tenant]
    Apartment::Tenant.switch!(tenant)
  end
end

This is for action mailer config/initializers/mail_delivery_job.rb:

module ActionMailer
  class MailDeliveryJob < ActiveJob::Base
    before_enqueue do |job|
      tenant = Apartment::Tenant.current
      args = job.arguments.last[:args]
      args.push({}) unless args.last.is_a?(Hash)
      args.last.merge!(tenant: tenant)
      job.arguments.last[:args] = args
    end

    before_perform do |job|
      args = job.arguments.last[:args]
      tenant = args.last[:tenant]
      Apartment::Tenant.switch!(tenant)
    end
  end
end

With this you can continue using your jobs and mailers without passing extra params and you get the correct tenant in your jobs.

I hope it is useful for someone.

Thank you, I will try this and let you know. this will be a game-changer for me.