Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom table names #748

Closed
gap777 opened this issue Nov 13, 2022 · 13 comments
Closed

Custom table names #748

gap777 opened this issue Nov 13, 2022 · 13 comments

Comments

@gap777
Copy link
Contributor

gap777 commented Nov 13, 2022

As of https://github.com/bensheldon/good_job/releases/tag/v2.11.2, good_jobs supported custom table names. However, this seems not to work anymore. Specifically, trying to set them in a config initializer

GoodJob::Process.table_name = 'my_good_job_processes'
GoodJob::ActiveJobJob.table_name = 'my_good_jobs'
GoodJob::Execution.table_name = 'my_good_jobs'

generates errors like:

.../config/initializers/good_job.rb:1:in `<main>': uninitialized constant GoodJob::Process (NameError)
17:06:22 web.1  |
17:06:22 web.1  | GoodJob::Process.table_name = 'my_good_job_processes'
17:06:22 web.1  |        ^^^^^^^^^

Is there another way to configure this, or is this capability lost?
Can it be restored?
Thank you!

@bensheldon
Copy link
Owner

bensheldon commented Nov 15, 2022

@gap777 Thanks for opening the issue and sorry about the inconvenience!

Those models became autoloaded. You should be able to do this in an an initializer:

# config/initializers/good_job.rb

Rails.application.reloader.to_prepare do
  GoodJob::Execution.table_name = 'my_good_jobs'
  GoodJob::Process.table_name = 'my_good_job_processes'
  GoodJob::Setting.table_name = 'my_good_job_settings' # <- new database backed model
end

Edit: GoodJob::Job's table name does not need to be set directly.

@remy727
Copy link
Contributor

remy727 commented Jan 31, 2023

@bensheldon, I am getting the following error with the above configuration.

/Users/admin/.rvm/gems/ruby-3.2.0/gems/good_job-3.8.0/app/models/good_job/job.rb:24:in `table_name=': Assign GoodJob::Execution.table_name directly (NotImplementedError)

What is the correct configuration in the latest version?

@bensheldon
Copy link
Owner

@remy727 oops, you don't need to set the table name for GoodJob::Job; it will automatically be set based on what GoodJob::Execution is named. I'll edit my original suggestion.

delegate :table_name, to: GoodJob::Execution
def table_name=(_value)
raise NotImplementedError, 'Assign GoodJob::Execution.table_name directly'
end

@remy727
Copy link
Contributor

remy727 commented Jan 31, 2023

Thank you for your reply @bensheldon
The error went way but I am still seeing the good_jobs not my_good_jobs in migration file.

@bensheldon
Copy link
Owner

@remy727 oh! Migrations/Schema and Model configuration aren't connected. If you want to rename the tables themselves, you'll have to write your own migrations.

@remy727
Copy link
Contributor

remy727 commented Jan 31, 2023

Got it. Thank you for confirming @bensheldon!

@mokolabs
Copy link

mokolabs commented Aug 7, 2023

I tried using the custom initializer code above and updated the migration to match my new table names.

But, when I relaunch the app after migrating, I'm seeing this error a lot in my logs:

DEPRECATION WARNING: GoodJob has pending database migrations. To create the migration files, run:
  rails generate good_job:update
To apply the migration files, run:
  rails db:migrate

Is there any way to disable that?

@bensheldon
Copy link
Owner

@mokolabs sorry about that! I maybe hardcoded a tablename in one of those checks 😰 I'll take a look because that is annoying.

@bensheldon
Copy link
Owner

I tried customizing them myself. I'm not seeing the migration warning, but I had to add a bunch more overrides:

Rails.application.reloader.to_prepare do
  GoodJob::BaseExecution.table_name = 'c_good_jobs'
  GoodJob::BatchRecord.table_name = 'c_good_jobs'
  GoodJob::DiscreteExecution.table_name = 'c_good_job_executions'
  GoodJob::Execution.table_name = 'c_good_jobs'
  GoodJob::Process.table_name = 'c_good_job_processes'
  GoodJob::Setting.table_name = 'c_good_job_settings'
end

@gap777
Copy link
Contributor Author

gap777 commented Aug 7, 2023

That's what mine looks like these days:

# MONKEYPATCH
Rails.application.reloader.to_prepare do
  GoodJob::BaseExecution.table_name = 'core_jobs__jobs'
  GoodJob::Execution.table_name = 'core_jobs__jobs'
  GoodJob::DiscreteExecution.table_name = 'core_jobs__executions'
  GoodJob::Process.table_name = 'core_jobs__processes'
  GoodJob::Setting.table_name = 'core_jobs__settings'
  GoodJob::BatchRecord.table_name = 'core_jobs__batches'
end

@gap777
Copy link
Contributor Author

gap777 commented Aug 7, 2023

FWIW, I'm not seeing the warning with the latest build... I think there one or two regressions in that particular area since the bug was originally fixed, though those have already been fixed as well in the latest.

@mokolabs
Copy link

mokolabs commented Aug 7, 2023

@bensheldon @gap777 Thank you for the quick reply! I'll give it another go. 👍🏻

@mokolabs
Copy link

mokolabs commented Aug 8, 2023

@bensheldon @gap777 That worked. Thanks again!

For those who wish to go down this path, here's everything you need to do it:

  1. Create a good_job initializer at config/initializers/good_job.rb.
  2. Add your custom table names to the initializer:
    # Rename good_job tables
    Rails.application.reloader.to_prepare do
      GoodJob::BaseExecution.table_name = 'jobs'
      GoodJob::BatchRecord.table_name = 'jobs_batches'
      GoodJob::DiscreteExecution.table_name = 'jobs_executions'
      GoodJob::Execution.table_name = 'jobs'
      GoodJob::Process.table_name = 'jobs_processes'
      GoodJob::Setting.table_name = 'jobs_settings'
    end
    
  3. Tweak the default good_job database migration to use your custom table names:
    class CreateGoodJobs < ActiveRecord::Migration[7.0]
      def change
        # Uncomment for Postgres v12 or earlier to enable gen_random_uuid() support
        # enable_extension 'pgcrypto'
    
        create_table :jobs, id: :uuid do |t|
          t.text :queue_name
          t.integer :priority
          t.jsonb :serialized_params
          t.datetime :scheduled_at
          t.datetime :performed_at
          t.datetime :finished_at
          t.text :error
    
          t.timestamps
    
          t.uuid :active_job_id
          t.text :concurrency_key
          t.text :cron_key
          t.uuid :retried_good_job_id
          t.datetime :cron_at
    
          t.uuid :batch_id
          t.uuid :batch_callback_id
    
          t.boolean :is_discrete
          t.integer :executions_count
          t.text :job_class
          t.integer :error_event, limit: 2
        end
    
        create_table :jobs_batches, id: :uuid do |t|
          t.timestamps
          t.text :description
          t.jsonb :serialized_properties
          t.text :on_finish
          t.text :on_success
          t.text :on_discard
          t.text :callback_queue_name
          t.integer :callback_priority
          t.datetime :enqueued_at
          t.datetime :discarded_at
          t.datetime :finished_at
        end
    
        create_table :jobs_executions, id: :uuid do |t|
          t.timestamps
    
          t.uuid :active_job_id, null: false
          t.text :job_class
          t.text :queue_name
          t.jsonb :serialized_params
          t.datetime :scheduled_at
          t.datetime :finished_at
          t.text :error
          t.integer :error_event, limit: 2
        end
    
        create_table :jobs_processes, id: :uuid do |t|
          t.timestamps
          t.jsonb :state
        end
    
        create_table :jobs_settings, id: :uuid do |t|
          t.timestamps
          t.text :key
          t.jsonb :value
          t.index :key, unique: true
        end
    
        add_index :jobs, :scheduled_at, where: "(finished_at IS NULL)", name: "index_jobs_on_scheduled_at"
        add_index :jobs, [:queue_name, :scheduled_at], where: "(finished_at IS NULL)", name: :index_jobs_on_queue_name_and_scheduled_at
        add_index :jobs, [:active_job_id, :created_at], name: :index_jobs_on_active_job_id_and_created_at
        add_index :jobs, :concurrency_key, where: "(finished_at IS NULL)", name: :index_jobs_on_concurrency_key_when_unfinished
        add_index :jobs, [:cron_key, :created_at], name: :index_jobs_on_cron_key_and_created_at
        add_index :jobs, [:cron_key, :cron_at], name: :index_jobs_on_cron_key_and_cron_at, unique: true
        add_index :jobs, [:active_job_id], name: :index_jobs_on_active_job_id
        add_index :jobs, [:finished_at], where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL", name: :index_jobs_on_finished_at
        add_index :jobs, [:priority, :created_at], order: { priority: "DESC NULLS LAST", created_at: :asc },
          where: "finished_at IS NULL", name: :index_jobs_on_priority_created_at_when_unfinished
        add_index :jobs, [:batch_id], where: "batch_id IS NOT NULL"
        add_index :jobs, [:batch_callback_id], where: "batch_callback_id IS NOT NULL"
    
        add_index :jobs_executions, [:active_job_id, :created_at], name: :index_jobs_executions_on_active_job_id_and_created_at
      end
    end
    
  4. Double-check your migration to make sure everything is updated.
  5. Run the migration.
  6. Your database should now contain the following tables:
    jobs
    jobs_batches
    jobs_executions
    jobs_processes
    jobs_settings
    
  7. Restart the app.
  8. And that should do it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

4 participants