Як налаштувати Solid Queue 1.0 для використання з однією базою даних та логуванням

Ви можете ознайомитись з документацією тут, але я надам вам покрокову інструкцію.

По-перше, НЕ використовуйте стандартний інсталятор нижче, якщо тільки ви не вважаєте, що файл db/queue_schema.rb застарілий порівняно з тим, що я надаю нижче. Якщо ви все ж вирішите скористатися цим, дозволяйте створення черги тільки для довідки, а потім негайно запобігайте переписуванню production.rb. Ми будемо оновлювати config/queue.yml згідно з наведеним нижче.

# Не використовуйте це для налаштування єдиної бази даних, якщо вам не потрібно більш актуальне  
# версія файлу `db/queue_schema.rb`

# rails solid_queue:install

# Це додасть/змодифікує наступне:

# створить config/queue.yml
# однаковий config/recurring.yml
# створить db/queue_schema.rb
# однаковий bin/jobs
# змінить config/environments/production.rb
  1. Створіть міграцію, яка містить всю інформацію з db/queue.rb (я надам свою нижче)
  2. Видаліть файл db/queue_schema.rb
  3. Оновіть файл config/database.yml
  4. Оновіть config/queue.yml
  5. Оновіть файли development.rb, test.rb та, можливо, production.rb
  6. Виконайте команду rails db:migrate
  7. Додайте рядок у development.rb для показу логів з bin/jobs

Налаштування конфігурації для єдиної бази даних

  1. Створіть міграцію з наступним вмістом або, для більш актуальної версії, використовуйте свій власний файл db/queue.rb.
    Якщо ви обрали підхід з інсталятором для новіших файлів, перенесіть вміст файлу db/queue.rb сюди.
class SolidQueueSetup < ActiveRecord::Migration[8.0]  
 def change  
 enable_extension "pg_catalog.plpgsql"  

 create_table "solid_queue_blocked_executions", force: :cascade do |t|  
 t.bigint "job_id", null: false  
 t.string "queue_name", null: false  
 t.integer "priority", default: 0, null: false  
 t.string "concurrency_key", null: false  
 t.datetime "expires_at", null: false  
 t.datetime "created_at", null: false  
 t.index ["concurrency_key", "priority", "job_id"], name: "index_solid_queue_blocked_executions_for_release"  
 t.index ["expires_at", "concurrency_key"], name: "index_solid_queue_blocked_executions_for_maintenance"  
 t.index ["job_id"], name: "index_solid_queue_blocked_executions_on_job_id", unique: true  
 end  

 create_table "solid_queue_claimed_executions", force: :cascade do |t|  
 t.bigint "job_id", null: false  
 t.bigint "process_id"  
 t.datetime "created_at", null: false  
 t.index ["job_id"], name: "index_solid_queue_claimed_executions_on_job_id", unique: true  
 t.index ["process_id", "job_id"], name: "index_solid_queue_claimed_executions_on_process_id_and_job_id"  
 end  

 create_table "solid_queue_failed_executions", force: :cascade do |t|  
 t.bigint "job_id", null: false  
 t.text "error"  
 t.datetime "created_at", null: false  
 t.index ["job_id"], name: "index_solid_queue_failed_executions_on_job_id", unique: true  
 end  

 create_table "solid_queue_jobs", force: :cascade do |t|  
 t.string "queue_name", null: false  
 t.string "class_name", null: false  
 t.text "arguments"  
 t.integer "priority", default: 0, null: false  
 t.string "active_job_id"  
 t.datetime "scheduled_at"  
 t.datetime "finished_at"  
 t.string "concurrency_key"  
 t.datetime "created_at", null: false  
 t.datetime "updated_at", null: false  
 t.index ["active_job_id"], name: "index_solid_queue_jobs_on_active_job_id"  
 t.index ["class_name"], name: "index_solid_queue_jobs_on_class_name"  
 t.index ["finished_at"], name: "index_solid_queue_jobs_on_finished_at"  
 t.index ["queue_name", "finished_at"], name: "index_solid_queue_jobs_for_filtering"  
 t.index ["scheduled_at", "finished_at"], name: "index_solid_queue_jobs_for_alerting"  
 end  

 create_table "solid_queue_pauses", force: :cascade do |t|  
 t.string "queue_name", null: false  
 t.datetime "created_at", null: false  
 t.index ["queue_name"], name: "index_solid_queue_pauses_on_queue_name", unique: true  
 end  

 create_table "solid_queue_processes", force: :cascade do |t|  
 t.string "kind", null: false  
 t.datetime "last_heartbeat_at", null: false  
 t.bigint "supervisor_id"  
 t.integer "pid", null: false  
 t.string "hostname"  
 t.text "metadata"  
 t.datetime "created_at", null: false  
 t.string "name", null: false  
 t.index ["last_heartbeat_at"], name: "index_solid_queue_processes_on_last_heartbeat_at"  
 t.index ["name", "supervisor_id"], name: "index_solid_queue_processes_on_name_and_supervisor_id", unique: true  
 t.index ["supervisor_id"], name: "index_solid_queue_processes_on_supervisor_id"  
 end  

 create_table "solid_queue_ready_executions", force: :cascade do |t|  
 t.bigint "job_id", null: false  
 t.string "queue_name", null: false  
 t.integer "priority", default: 0, null: false  
 t.datetime "created_at", null: false  
 t.index ["job_id"], name: "index_solid_queue_ready_executions_on_job_id", unique: true  
 t.index ["priority", "job_id"], name: "index_solid_queue_poll_all"  
 t.index ["queue_name", "priority", "job_id"], name: "index_solid_queue_poll_by_queue"  
 end  

 create_table "solid_queue_recurring_executions", force: :cascade do |t|  
 t.bigint "job_id", null: false  
 t.string "task_key", null: false  
 t.datetime "run_at", null: false  
 t.datetime "created_at", null: false  
 t.index ["job_id"], name: "index_solid_queue_recurring_executions_on_job_id", unique: true  

t.index ["task_key", "run_at"], name: "index_solid_queue_recurring_executions_on_task_key_and_run_at", unique: true  
 end  

 create_table "solid_queue_recurring_tasks", force: :cascade do |t|  
 t.string "key", null: false  
 t.string "schedule", null: false  
 t.string "command", limit: 2048  
 t.string "class_name"  
 t.text "arguments"  
 t.string "queue_name"  
 t.integer "priority", default: 0  
 t.boolean "static", default: true, null: false  
 t.text "description"  
 t.datetime "created_at", null: false  
 t.datetime "updated_at", null: false  
 t.index ["key"], name: "index_solid_queue_recurring_tasks_on_key", unique: true  
 t.index ["static"], name: "index_solid_queue_recurring_tasks_on_static"  
 end  

 create_table "solid_queue_scheduled_executions", force: :cascade do |t|  
 t.bigint "job_id", null: false  
 t.string "queue_name", null: false  
 t.integer "priority", default: 0, null: false  
 t.datetime "scheduled_at", null: false  
 t.datetime "created_at", null: false  
 t.index ["job_id"], name: "index_solid_queue_scheduled_executions_on_job_id", unique: true  
 t.index ["scheduled_at", "priority", "job_id"], name: "index_solid_queue_dispatch_all"  
 end  

 create_table "solid_queue_semaphores", force: :cascade do |t|  
 t.string "key", null: false  
 t.integer "value", default: 1, null: false  
 t.datetime "expires_at", null: false  
 t.datetime "created_at", null: false  
 t.datetime "updated_at", null: false  
 t.index ["expires_at"], name: "index_solid_queue_semaphores_on_expires_at"  
 t.index ["key", "value"], name: "index_solid_queue_semaphores_on_key_and_value"  
 t.index ["key"], name: "index_solid_queue_semaphores_on_key", unique: true  
 end  



 create_table "solid_cache_entries", force: :cascade do |t|  
 t.binary "key", null: false  
 t.binary "value", null: false  
 t.datetime "created_at", null: false  
 t.bigint "key_hash", null: false  
 t.integer "byte_size", null: false  
 t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size"  
 t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size"  
 t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true  
 end  

 add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade  
 add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade  
 add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade  
 add_foreign_key "solid_queue_ready_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade  
 add_foreign_key "solid_queue_recurring_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade  
 add_foreign_key "solid_queue_scheduled_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade  
 end  
end

2.
Delete the db/queue.rb file

  1. Update database.yml with the following

Note: This is if you assign the database by URL

# PostgreSQL. Versions 9.3 and up are supported.  
#  
# Install the pg driver:  
# gem install pg  
# On macOS with Homebrew:  
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config  
# On Windows:  
# gem install pg  
# Choose the win32 build.  
# Install PostgreSQL and put its /bin directory on your path.  
#  
# Configure Using Gemfile  
# gem "pg"  
#  
default: &default  
 adapter: postgresql  
 encoding: unicode  
 # For details on connection pooling, see Rails configuration guide  
 # https://guides.rubyonrails.org/configuring.html#database-pooling  
 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>  


development:  
 <<: *default  
 database: your_app_development  

 # The specified database role being used to connect to PostgreSQL.  
 # To create additional roles in PostgreSQL see `$ createuser --help`.  
 # When left blank, PostgreSQL will use the default role. This is  
 # the same name as the operating system user running Rails.  
 #username: your_app  

 # The password associated with the PostgreSQL role (username).  
 #password:  

 # Connect on a TCP socket. Omitted by default since the client uses a  
 # domain socket that doesn't need configuration. Windows does not have  
 # domain sockets, so uncomment these lines.  
 #host: localhost  

 # The TCP port the server listens on. Defaults to 5432.  
 # If your server runs on a different port number, change accordingly.  
 #port: 5432  

 # Schema search path. The server defaults to $user,public  
 #schema_search_path: myapp,sharedapp,public  

 # Minimum log levels, in increasing order:  
 # debug5, debug4, debug3, debug2, debug1,  
 # log, notice, warning, error, fatal, and panic  
 # Defaults to warning.  
 #min_messages: notice  

# Warning: The database defined as "test" will be erased and  
# re-generated from your development database when you run "rake".  
# Do not set this db to the same as development or production.  
test:  
 <<: *default  
 database: your_app_test  

# As with config/credentials.yml, you never want to store sensitive information,  
# like your database password, in your source code. If your source code is  
# ever seen by anyone, they now have access to your database.  
#  
# Instead, provide the password or a full connection URL as an environment  
# variable when you boot the app. For example:  
#  
# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"  
#  
# If the connection URL is provided in the special DATABASE_URL environment  
# variable, Rails will automatically merge its configuration values on top of  
# the values provided in this file. Alternatively, you can specify a connection  
# URL environment variable explicitly:  
#  
# production:  
# url: <%= ENV["MY_APP_DATABASE_URL"] %>  
#  
# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database  
# for a full overview on how database connection configuration can be specified.  
#  
production:  
 <<: *default  
 url: <%= ENV["DATABASE_URL"] %>
  1. Update config/queue.ymlwith the following to make sure it targets the single database.
default: &default  
 dispatchers:  
 - polling_interval: 1  
 batch_size: 500  
 workers:  
 - queues: "*"  
 threads: 3  
 processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %>  
 polling_interval: 0.1  

development:  
 <<: *default  
 database: your_app_development  

test:  
 <<: *default  
 database: your_app_test  

production:  
 <<: *default  
 url: <%= ENV["DATABASE_URL"] %>
  1. Update develpment.rb/test.rb/production.rb to have this. It will tell active job to use solid queue. This should be in production.rb already, but will not be in development.rb & test.rb
Rails.application.configure do  
# ....  
 config.active_job.queue_adapter = :solid_queue  
# ....
end

Якщо ви бачите це, видаліть наступне з production.rb (та з development.rb/test.rb, якщо це там є). Це вказує solid queue на використання бази даних під назвою 'queue', яка не існує, для виконання міграцій і записів.

config.solid_queue.connects_to = { database: { writing: :queue } }
  1. Запустіть rails db:migrate

Реалізація логування в локальному bin/jobs

Якщо ви запускаєте bin/jobs і не бачите нічого, то це для вас.

Зазвичай усі логи bin/jobs потрапляють в logs/development.log, але з цією зміною вони будуть відображатись в консолі. Якщо ви хочете мати кращі логи, закоментуйте цю зміну і використовуйте logs/development.log, тому що він надасть стек-трейси, на відміну від ActiveSupport::Logger.new(STDOUT).

Щоб це зробити, переконайтесь, що у вашому файлі development.rb є наступне:

Rails.application.configure do  
 # ....  
 config.solid_queue.logger = ActiveSupport::Logger.new(STDOUT)  
 # ...  
end

Сподіваюсь, це допоможе!

Перекладено з: How to setup Solid Queue 1.0 for Single Database & Logging

Leave a Reply

Your email address will not be published. Required fields are marked *