Clockwork with a multi-tenant setup

99 views Asked by At

My app uses postgres schemas to implement multi-tenancy. So for a table like users, each tenant actually has it's own users table -

  • public.users (default)
  • foo.users
  • bar.users
  • ...

As a side note, it implements multi-tenancy using the apartment gem

The clockwork gem allows you to read events from a database table, with the use of it's sync_database_events method. For example, it can read events from a scheduled_jobs table/model:

sync_database_events model: ScheduledJob, every: 1.minute do |model_instance|
  rake model_instance.name
end

By default this reads from public.scheduled_jobs, but each one of my schemas will have it's own scheduled_jobs to read from.

Is there a convenient way to have it loop through all my tenants?

1

There are 1 answers

0
fuzzygroup On

I'm doing a very similar thing with the difference that I'm using Apartment and MySQL not Postgres. Apartment is very, very powerful but it feels poorly documented at best. Here was how I approached this:

if Rails.env.development?
  every(1.day, '3am.job -- Daily Job', :at => '03:00') do |job|
    User.delay.crawl
    Search.delay.crawl 
  end
elsif Rails.env.production?
  every(1.day, '3am.job -- Daily Job', :at => '03:00') do |job|
    SiteApi.usernames.each do |username|
      Apartment::Tenant.switch!(username)
      User.delay.crawl
      Search.delay.crawl        
    end
  end
end

The magic happens in my Rails.env.production? block. SiteApi is an API that talks to my master database of users and gets back an array of usernames. It then calls Apartment::Tenant.switch!(username) to switch the tenancy context to the right user. It then calls the functions that I need to run on each tenant.

You should note that I am also making use of the Apartment Sidekiq extension for delay.

I suspect this conceptual leap is what you're looking for.