diff --git a/Gemfile b/Gemfile index 9f414dfb..6265704d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,9 @@ source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -git_source(:bc) { |repo| "https://github.com/basecamp/#{repo}" } # Specify your gem's dependencies in mission_control-jobs.gemspec. gemspec +gem "solid_queue", github: "rails/solid_queue", branch: "improve-recurring-tasks-config" + gem "capybara", github: "teamcapybara/capybara" diff --git a/Gemfile.lock b/Gemfile.lock index b0434c1c..c06c7190 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,16 @@ +GIT + remote: https://github.com/rails/solid_queue.git + revision: 8df600df2d22261cdce3e51e103c1cf58d4da391 + branch: improve-recurring-tasks-config + specs: + solid_queue (0.8.2) + activejob (>= 7.1) + activerecord (>= 7.1) + concurrent-ruby (>= 1.3.1) + fugit (~> 1.11.0) + railties (>= 7.1) + thor (~> 1.3.1) + GIT remote: https://github.com/teamcapybara/capybara.git revision: c0cbf4024c1abd48b0c22c2930e7b05af58ab284 @@ -117,7 +130,7 @@ GEM erubi (1.12.0) et-orbi (1.2.11) tzinfo - fugit (1.11.0) + fugit (1.11.1) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) globalid (1.2.1) @@ -294,12 +307,6 @@ GEM rack-protection (= 4.0.0) rack-session (>= 2.0.0, < 3) tilt (~> 2.0) - solid_queue (0.5.0) - activejob (>= 7.1) - activerecord (>= 7.1) - concurrent-ruby (>= 1.3.1) - fugit (~> 1.11.0) - railties (>= 7.1) sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -357,7 +364,7 @@ DEPENDENCIES rubocop-performance rubocop-rails-omakase selenium-webdriver - solid_queue (>= 0.5) + solid_queue! sprockets-rails sqlite3 diff --git a/README.md b/README.md index 0286948e..5c740e26 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ This library extends Active Job with a querying interface and the following sett ## Adapter Specifics - **Resque**: Queue pausing is supported only if you have `resque-pause` installed in your project -- **Solid Queue**: Requires version >= 0.5. +- **Solid Queue**: Requires version >= 0.9. ## Advanced configuration diff --git a/app/models/mission_control/jobs/recurring_task.rb b/app/models/mission_control/jobs/recurring_task.rb index aa601731..93fd2b6d 100644 --- a/app/models/mission_control/jobs/recurring_task.rb +++ b/app/models/mission_control/jobs/recurring_task.rb @@ -1,7 +1,7 @@ class MissionControl::Jobs::RecurringTask include ActiveModel::Model - attr_accessor :id, :job_class_name, :arguments, :schedule, :last_enqueued_at + attr_accessor :id, :job_class_name, :command, :arguments, :schedule, :last_enqueued_at, :queue_name, :priority def initialize(queue_adapter: ActiveJob::Base.queue_adapter, **kwargs) @queue_adapter = queue_adapter diff --git a/app/views/mission_control/jobs/recurring_tasks/_general_information.html.erb b/app/views/mission_control/jobs/recurring_tasks/_general_information.html.erb index a234414c..2b8c3980 100644 --- a/app/views/mission_control/jobs/recurring_tasks/_general_information.html.erb +++ b/app/views/mission_control/jobs/recurring_tasks/_general_information.html.erb @@ -1,16 +1,37 @@ - - - - - - - - + <% if recurring_task.job_class_name.present? %> + + + + + + + + + + <% elsif recurring_task.command.present? %> + + + + + <% end %> + + <% if recurring_task.queue_name.present? %> + + + + + <% end %> + <% if recurring_task.priority.present? %> + + + + + <% end %>
Job class<%= recurring_task.job_class_name %>
Arguments
<%= recurring_task.arguments.join(",") %>
Job class<%= recurring_task.job_class_name %>
Arguments
<%= recurring_task.arguments.join(",") %>
Command
<%= recurring_task.command %>
Schedule <%= recurring_task.schedule %>
Queue<%= recurring_task.queue_name %>
Priority<%= recurring_task.priority %>
diff --git a/app/views/mission_control/jobs/recurring_tasks/_recurring_task.html.erb b/app/views/mission_control/jobs/recurring_tasks/_recurring_task.html.erb index dfa07bcf..c7d3204b 100644 --- a/app/views/mission_control/jobs/recurring_tasks/_recurring_task.html.erb +++ b/app/views/mission_control/jobs/recurring_tasks/_recurring_task.html.erb @@ -3,10 +3,14 @@ <%= link_to recurring_task.id, application_recurring_task_path(@application, recurring_task.id) %> - <%= link_to recurring_task.job_class_name, application_recurring_task_path(@application, recurring_task.id) %> + <% if recurring_task.job_class_name.present? %> + <%= recurring_task.job_class_name %> - <% if recurring_task.arguments.present? %> -
<%= recurring_task.arguments.join(",") %>
+ <% if recurring_task.arguments.present? %> +
<%= recurring_task.arguments.join(",") %>
+ <% end %> + <% elsif recurring_task.command.present? %> +
<%= recurring_task.command %>
<% end %> <%= recurring_task.schedule %> diff --git a/lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb b/lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb index 4d40b456..864a9132 100644 --- a/lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb +++ b/lib/active_job/queue_adapters/solid_queue_ext/recurring_tasks.rb @@ -25,8 +25,11 @@ def recurring_task_attributes_from_solid_queue_recurring_task(task) { id: task.key, job_class_name: task.class_name, + command: task.command, arguments: task.arguments, - schedule: task.schedule + schedule: task.schedule, + queue_name: task.queue_name, + priority: task.priority } end diff --git a/mission_control-jobs.gemspec b/mission_control-jobs.gemspec index 1611e53b..9b886316 100644 --- a/mission_control-jobs.gemspec +++ b/mission_control-jobs.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |spec| spec.add_dependency "irb", "~> 1.13" spec.add_development_dependency "resque" - spec.add_development_dependency "solid_queue", ">= 0.5" + spec.add_development_dependency "solid_queue", ">= 0.9" spec.add_development_dependency "selenium-webdriver" spec.add_development_dependency "resque-pause" spec.add_development_dependency "mocha" diff --git a/test/controllers/recurring_tasks_controller_test.rb b/test/controllers/recurring_tasks_controller_test.rb index f24c0794..a3d55cf4 100644 --- a/test/controllers/recurring_tasks_controller_test.rb +++ b/test/controllers/recurring_tasks_controller_test.rb @@ -13,20 +13,20 @@ class MissionControl::Jobs::RecurringTasksControllerTest < ActionDispatch::Integ end test "get recurring task list" do - dispatch_jobs_async(wait: 2.seconds) do + schedule_recurring_tasks_async(wait: 2.seconds) do get mission_control_jobs.application_recurring_tasks_url(@application) assert_response :ok assert_select "tr.recurring_task", 1 assert_select "td a", "periodic_pause_job" - assert_select "td a", "PauseJob" + assert_select "td", "PauseJob" assert_select "td", "every second" assert_select "td", /less than \d+ seconds ago/ end end test "get recurring task details and job list" do - dispatch_jobs_async(wait: 1.seconds) do + schedule_recurring_tasks_async(wait: 1.seconds) do get mission_control_jobs.application_recurring_task_url(@application, "periodic_pause_job") assert_response :ok @@ -39,7 +39,7 @@ class MissionControl::Jobs::RecurringTasksControllerTest < ActionDispatch::Integ end test "redirect to recurring tasks list when recurring task doesn't exist" do - dispatch_jobs_async do + schedule_recurring_tasks_async do get mission_control_jobs.application_recurring_task_url(@application, "invalid_key") assert_redirected_to mission_control_jobs.application_recurring_tasks_url(@application) diff --git a/test/dummy/db/migrate/20240909204134_add_name_to_processes.solid_queue.rb b/test/dummy/db/migrate/20240909204134_add_name_to_processes.solid_queue.rb new file mode 100644 index 00000000..d5c14cda --- /dev/null +++ b/test/dummy/db/migrate/20240909204134_add_name_to_processes.solid_queue.rb @@ -0,0 +1,6 @@ +# This migration comes from solid_queue (originally 20240811173327) +class AddNameToProcesses < ActiveRecord::Migration[7.1] + def change + add_column :solid_queue_processes, :name, :string + end +end diff --git a/test/dummy/db/migrate/20240909204135_make_name_not_null.solid_queue.rb b/test/dummy/db/migrate/20240909204135_make_name_not_null.solid_queue.rb new file mode 100644 index 00000000..f56dd4d3 --- /dev/null +++ b/test/dummy/db/migrate/20240909204135_make_name_not_null.solid_queue.rb @@ -0,0 +1,17 @@ +# This migration comes from solid_queue (originally 20240813160053) +class MakeNameNotNull < ActiveRecord::Migration[7.1] + def up + SolidQueue::Process.where(name: nil).find_each do |process| + process.name ||= [ process.kind.downcase, SecureRandom.hex(10) ].join("-") + process.save! + end + + change_column :solid_queue_processes, :name, :string, null: false + add_index :solid_queue_processes, [ :name, :supervisor_id ], unique: true + end + + def down + remove_index :solid_queue_processes, [ :name, :supervisor_id ] + change_column :solid_queue_processes, :name, :string, null: true + end +end diff --git a/test/dummy/db/migrate/20240909204136_change_solid_queue_recurring_tasks_static_to_not_null.solid_queue.rb b/test/dummy/db/migrate/20240909204136_change_solid_queue_recurring_tasks_static_to_not_null.solid_queue.rb new file mode 100644 index 00000000..325320a0 --- /dev/null +++ b/test/dummy/db/migrate/20240909204136_change_solid_queue_recurring_tasks_static_to_not_null.solid_queue.rb @@ -0,0 +1,6 @@ +# This migration comes from solid_queue (originally 20240819165045) +class ChangeSolidQueueRecurringTasksStaticToNotNull < ActiveRecord::Migration[7.1] + def change + change_column_null :solid_queue_recurring_tasks, :static, false, true + end +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb index 84c47c16..02438592 100644 --- a/test/dummy/db/schema.rb +++ b/test/dummy/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_08_06_160416) do +ActiveRecord::Schema[7.1].define(version: 2024_09_09_204136) do create_table "posts", force: :cascade do |t| t.string "title" t.text "body" @@ -77,7 +77,9 @@ 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 @@ -108,7 +110,7 @@ t.text "arguments" t.string "queue_name" t.integer "priority", default: 0 - t.boolean "static", default: true + t.boolean "static", default: true, null: false t.text "description" t.datetime "created_at", null: false t.datetime "updated_at", null: false diff --git a/test/test_helper.rb b/test/test_helper.rb index 06e40c9e..bb458fbd 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -81,12 +81,12 @@ class ActionDispatch::IntegrationTest @worker = SolidQueue::Worker.new(queues: "*", threads: 2, polling_interval: 0.01) recurring_task = { periodic_pause_job: { class: "PauseJob", schedule: "every second" } } - @dispatcher = SolidQueue::Dispatcher.new(recurring_tasks: recurring_task) + @scheduler = SolidQueue::Scheduler.new(recurring_tasks: recurring_task) end teardown do @worker.stop - @dispatcher.stop + @scheduler.stop end private @@ -95,7 +95,7 @@ def queue_adapter_for_test end def register_workers(count: 1) - count.times { |i| SolidQueue::Process.register(kind: "Worker", pid: i) } + count.times { |i| SolidQueue::Process.register(kind: "Worker", pid: i, name: "worker-#{i}") } end def perform_enqueued_jobs_async(wait: 1.second) @@ -106,11 +106,11 @@ def perform_enqueued_jobs_async(wait: 1.second) @worker.stop end - def dispatch_jobs_async(wait: 1.second) - @dispatcher.start + def schedule_recurring_tasks_async(wait: 1.second) + @scheduler.start sleep(wait) yield if block_given? - @dispatcher.stop + @scheduler.stop end end