Closed22

gem maintenance_tasksを使ってみる

あっきーあっきー

ドキュメントに沿ってmaintenance_tasksをインストール

bundle add maintenance_tasks
bin/rails generate maintenance_tasks:install
あっきーあっきー

必要なテーブルが作成された

$ bin/rails generate maintenance_tasks:install
       route  mount MaintenanceTasks::Engine, at: "/maintenance_tasks"
        rake  maintenance_tasks:install:migrations
Copied migration 20241109052504_create_maintenance_tasks_runs.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052505_change_cursor_to_string.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052506_remove_index_on_task_name.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052507_add_arguments_to_maintenance_tasks_runs.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052508_add_lock_version_to_maintenance_tasks_runs.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052509_change_runs_tick_columns_to_bigints.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052510_add_index_on_task_name_and_status_to_runs.maintenance_tasks.rb from maintenance_tasks
Copied migration 20241109052511_add_metadata_to_runs.maintenance_tasks.rb from maintenance_tasks
        rake  db:migrate
== 20241109052504 CreateMaintenanceTasksRuns: migrating =======================
-- create_table(:maintenance_tasks_runs)
   -> 0.0051s
== 20241109052504 CreateMaintenanceTasksRuns: migrated (0.0052s) ==============

== 20241109052505 ChangeCursorToString: migrating =============================
-- change_table(:maintenance_tasks_runs)
   -> 0.0414s
== 20241109052505 ChangeCursorToString: migrated (0.0414s) ====================

== 20241109052506 RemoveIndexOnTaskName: migrating ============================
-- change_table(:maintenance_tasks_runs)
   -> 0.0018s
== 20241109052506 RemoveIndexOnTaskName: migrated (0.0018s) ===================

== 20241109052507 AddArgumentsToMaintenanceTasksRuns: migrating ===============
-- add_column(:maintenance_tasks_runs, :arguments, :text)
   -> 0.0015s
== 20241109052507 AddArgumentsToMaintenanceTasksRuns: migrated (0.0016s) ======

== 20241109052508 AddLockVersionToMaintenanceTasksRuns: migrating =============
-- add_column(:maintenance_tasks_runs, :lock_version, :integer, {:default=>0, :null=>false})
   -> 0.0014s
== 20241109052508 AddLockVersionToMaintenanceTasksRuns: migrated (0.0015s) ====

== 20241109052509 ChangeRunsTickColumnsToBigints: migrating ===================
-- change_table(:maintenance_tasks_runs, {:bulk=>true})
   -> 0.0368s
== 20241109052509 ChangeRunsTickColumnsToBigints: migrated (0.0368s) ==========

== 20241109052510 AddIndexOnTaskNameAndStatusToRuns: migrating ================
-- remove_index(:maintenance_tasks_runs, {:column=>[:task_name, :created_at], :order=>{:created_at=>:desc}, :name=>:index_maintenance_tasks_runs_on_task_name_and_created_at})
   -> 0.0014s
-- add_index(:maintenance_tasks_runs, [:task_name, :status, :created_at], {:name=>:index_maintenance_tasks_runs, :order=>{:created_at=>:desc}})
   -> 0.0007s
== 20241109052510 AddIndexOnTaskNameAndStatusToRuns: migrated (0.0022s) =======

== 20241109052511 AddMetadataToRuns: migrating ================================
-- add_column(:maintenance_tasks_runs, :metadata, :text)
   -> 0.0014s
== 20241109052511 AddMetadataToRuns: migrated (0.0015s) =======================
あっきーあっきー

新しいタスクを作る

$ bin/rails generate maintenance_tasks:task my_task
      create  app/tasks/maintenance/my_task.rb
      create  test/tasks/maintenance/my_task_test.rb
あっきーあっきー

app/tasks に作られるの良い
lib/tasks にrake task入れてるのちょっと不思議なイメージあったので

あっきーあっきー

生成されたファイル

app/tasks/maintenance/my_task.rb
# frozen_string_literal: true

module Maintenance
  class MyTask < MaintenanceTasks::Task
    def collection
      # Collection to be iterated over
      # Must be Active Record Relation or Array
    end

    def process(element)
      # The work to be done in a single iteration of the task.
      # This should be idempotent, as the same element may be processed more
      # than once if the task is interrupted and resumed.
    end

    def count
      # Optionally, define the number of rows that will be iterated over
      # This is used to track the task's progress
    end
  end
end

あっきーあっきー

何かしらのコレクション操作のようなので適当にデータを作っておく

bin/rails g model Post title:string content:text
bin/rails db:migrate
rails c

100.times { |i| Post.create(title: "title #{i}", content: "content #{i}") }
あっきーあっきー

Postを全件出すだけの処理にして保存

# frozen_string_literal: true

module Maintenance
  class MyTask < MaintenanceTasks::Task
    def collection
      Post.all
    end

    def process(element)
      puts "Processing post: #{element.title}"
    end

    def count
      # Optionally, define the number of rows that will be iterated over
      # This is used to track the task's progress
    end
  end
end
あっきーあっきー

Runを実行したログ

Started POST "/maintenance_tasks/tasks/Maintenance::MyTask/runs" for 127.0.0.1 at 2024-11-09 14:42:50 +0900
Processing by MaintenanceTasks::RunsController#create as HTML
  Parameters: {"authenticity_token"=>"[FILTERED]", "commit"=>"Run", "task_id"=>"Maintenance::MyTask"}
  TRANSACTION (0.1ms)  BEGIN immediate TRANSACTION /*action='create',application='TestApp',controller='runs'*/
  MaintenanceTasks::Run Create (1.4ms)  INSERT INTO "maintenance_tasks_runs" ("task_name", "started_at", "ended_at", "time_running", "tick_count", "tick_total", "job_id", "cursor", "status", "error_class", "error_message", "backtrace", "created_at", "updated_at", "arguments", "lock_version", "metadata") VALUES ('Maintenance::MyTask', NULL, NULL, 0.0, NULL, NULL, 'ee29af71-5053-4156-9ba5-f8f449e621c2', NULL, 'enqueued', NULL, NULL, NULL, '2024-11-09 05:42:50.131892', '2024-11-09 05:42:50.131892', '{}', 0, NULL) RETURNING "id" /*action='create',application='TestApp',controller='runs'*/
  TRANSACTION (6.6ms)  COMMIT TRANSACTION /*action='create',application='TestApp',controller='runs'*/
[ActiveJob] Enqueued MaintenanceTasks::TaskJob (Job ID: ee29af71-5053-4156-9ba5-f8f449e621c2) to Async(default) with arguments: #<GlobalID:0x00007f1ed8a6c7c0 @uri=#<URI::GID gid://test-app/MaintenanceTasks::Run/1>>
Redirected to http://127.0.0.1:3000/maintenance_tasks/tasks/Maintenance::MyTask
Completed 302 Found in 56ms (ActiveRecord: 8.2ms (1 query, 0 cached) | GC: 0.4ms)


[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Load (0.1ms)  SELECT "maintenance_tasks_runs".* FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 LIMIT 1 /*application='TestApp'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2] Performing MaintenanceTasks::TaskJob (Job ID: ee29af71-5053-4156-9ba5-f8f449e621c2) from Async(default) enqueued at 2024-11-09T05:42:50.145454321Z with arguments: #<GlobalID:0x00007f1ed8b1a500 @uri=#<URI::GID gid://test-app/MaintenanceTasks::Run/1>>
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.0ms)  BEGIN immediate TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Update (1.4ms)  UPDATE "maintenance_tasks_runs" SET "status" = 'running', "updated_at" = '2024-11-09 05:42:50.156100', "lock_version" = 1 WHERE "maintenance_tasks_runs"."id" = 1 AND "maintenance_tasks_runs"."lock_version" = 0 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.1ms)  COMMIT TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Started GET "/maintenance_tasks/tasks/Maintenance::MyTask" for 127.0.0.1 at 2024-11-09 14:42:50 +0900
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.0ms)  BEGIN immediate TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Update (1.5ms)  UPDATE "maintenance_tasks_runs" SET "started_at" = '2024-11-09 05:42:50.165353', "updated_at" = '2024-11-09 05:42:50.165564', "lock_version" = 2 WHERE "maintenance_tasks_runs"."id" = 1 AND "maintenance_tasks_runs"."lock_version" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.1ms)  COMMIT TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   Post Load (0.3ms)  SELECT "posts".* FROM "posts" ORDER BY posts.id LIMIT 100 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 0
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 1
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 2
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.5ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 3
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 4
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 5
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.2ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 6
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 7
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 8
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 9
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
Processing post: title 10

~~~Processing post: title 99まで続く~~~

[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   Post Load (0.1ms)  SELECT "posts".* FROM "posts" WHERE (posts.id > 200) ORDER BY posts.id LIMIT 100 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Update All (0.1ms)  UPDATE "maintenance_tasks_runs" SET "tick_count" = COALESCE("tick_count", 0) + 100, "time_running" = COALESCE("time_running", 0) + 0.184634612, "lock_version" = COALESCE("lock_version", 0) + 1, "updated_at" = '2024-11-09 05:42:50.347492' WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2] [JobIteration::Iteration] Completed iterating. times_interrupted=0 total_time=0.185
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.0ms)  BEGIN immediate TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Update (1.0ms)  UPDATE "maintenance_tasks_runs" SET "status" = 'succeeded', "ended_at" = '2024-11-09 05:42:50.348916', "cursor" = '200', "updated_at" = '2024-11-09 05:42:50.349333', "lock_version" = 4 WHERE "maintenance_tasks_runs"."id" = 1 AND "maintenance_tasks_runs"."lock_version" = 3 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.1ms)  COMMIT TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2] Performed MaintenanceTasks::TaskJob (Job ID: ee29af71-5053-4156-9ba5-f8f449e621c2) from Async(default) in 202.35ms
  MaintenanceTasks::Run Load (0.2ms)  SELECT "maintenance_tasks_runs".* FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."task_name" = 'Maintenance::MyTask' AND "maintenance_tasks_runs"."status" IN ('enqueued', 'running', 'paused', 'pausing', 'cancelling', 'interrupted') ORDER BY "maintenance_tasks_runs"."created_at" DESC /*action='show',application='TestApp',controller='tasks'*/
  MaintenanceTasks::Run Load (0.2ms)  SELECT "maintenance_tasks_runs".* FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."task_name" = 'Maintenance::MyTask' AND "maintenance_tasks_runs"."status" IN ('succeeded', 'errored', 'cancelled') ORDER BY "maintenance_tasks_runs"."created_at" DESC LIMIT 21 /*action='show',application='TestApp',controller='tasks'*/
  Rendering layout /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/layouts/maintenance_tasks/application.html.erb
  Rendering /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/tasks/show.html.erb within layouts/maintenance_tasks/application
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/tasks/_custom.html.erb (Duration: 0.0ms | GC: 0.0ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/runs/info/_succeeded.html.erb (Duration: 0.7ms | GC: 0.0ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/runs/info/_custom.html.erb (Duration: 0.1ms | GC: 0.0ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/runs/_csv.html.erb (Duration: 0.3ms | GC: 0.0ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/runs/_arguments.html.erb (Duration: 0.2ms | GC: 0.0ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/runs/_metadata.html.erb (Duration: 0.2ms | GC: 0.0ms)
  Rendered collection of /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/runs/_run.html.erb [1 times] (Duration: 10.8ms | GC: 0.6ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/maintenance_tasks/tasks/show.html.erb within layouts/maintenance_tasks/application (Duration: 14.2ms | GC: 0.6ms)
  Rendered /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/layouts/maintenance_tasks/_navbar.html.erb (Duration: 0.1ms | GC: 0.0ms)
  Rendered layout /home/akinov/.rbenv/versions/3.3.6/lib/ruby/gems/3.3.0/gems/maintenance_tasks-2.8.0/app/views/layouts/maintenance_tasks/application.html.erb (Duration: 15.1ms | GC: 0.6ms)
Completed 200 OK in 107ms (Views: 15.4ms | ActiveRecord: 0.3ms (2 queries, 0 cached) | GC: 9.6ms)
あっきーあっきー

ActiveJobでバックグラウンドで実行され詳細ページで実行結果が確認できた

あっきーあっきー

maintenance_tasks_runsには何が入っているのか

sqlite> select * from maintenance_tasks_runs;

id|task_name|started_at|ended_at|time_running|tick_count|tick_total|job_id|cursor|status|error_class|error_message|backtrace|created_at|updated_at|arguments|lock_version|metadata
1|Maintenance::MyTask|2024-11-09 05:42:50.165353|2024-11-09 05:42:50.348916|0.184634612|100||ee29af71-5053-4156-9ba5-f8f449e621c2|200|succeeded||||2024-11-09 05:42:50.131892|2024-11-09 05:42:50.349333|{}|4|
あっきーあっきー

途中のSQL見ると常にstatus、lock_versionを確認しながら実行しているぽい

MaintenanceTasks::Run Pluck (0.1ms)  SELECT "maintenance_tasks_runs"."status", "maintenance_tasks_runs"."lock_version" FROM "maintenance_tasks_runs" WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/

途中updateは入らず、強制終了などされた場合にcursorなどが更新される?

処理がすべて終了するとupdate が走っていた

[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Update All (0.1ms)  UPDATE "maintenance_tasks_runs" SET "tick_count" = COALESCE("tick_count", 0) + 100, "time_running" = COALESCE("time_running", 0) + 0.184634612, "lock_version" = COALESCE("lock_version", 0) + 1, "updated_at" = '2024-11-09 05:42:50.347492' WHERE "maintenance_tasks_runs"."id" = 1 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2] [JobIteration::Iteration] Completed iterating. times_interrupted=0 total_time=0.185
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   TRANSACTION (0.0ms)  BEGIN immediate TRANSACTION /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
[ActiveJob] [MaintenanceTasks::TaskJob] [ee29af71-5053-4156-9ba5-f8f449e621c2]   MaintenanceTasks::Run Update (1.0ms)  UPDATE "maintenance_tasks_runs" SET "status" = 'succeeded', "ended_at" = '2024-11-09 05:42:50.348916', "cursor" = '200', "updated_at" = '2024-11-09 05:42:50.349333', "lock_version" = 4 WHERE "maintenance_tasks_runs"."id" = 1 AND "maintenance_tasks_runs"."lock_version" = 3 /*application='TestApp',job='MaintenanceTasks%3A%3ATaskJob'*/
あっきーあっきー

Custom Task Parameters

attribute追加でパラメータを利用可能

attribute :updated_content, :string
あっきーあっきー

指定したパラメータでtitleを上書きするタスクに変更した

# frozen_string_literal: true

module Maintenance
  class MyTask < MaintenanceTasks::Task
    attribute :title, :string
    validates :title, presence: true

    def collection
      Post.all
    end

    def process(element)
      element.update(title: title)
    end
  end
end
あっきーあっきー

入力フォームが出現。
validateも設定できるので安全に実行できそう

あっきーあっきー

collectionが空になる条件で実行したところ succeededなのにProccessed items. の状態でプログレスバーが動く様になってしまった。
ここは注意が必要かも

あっきーあっきー

対象のJobを引数指定して呼び出すだけのようなユースケースで使いたい

# app/tasks/maintenance/no_collection_task.rb

module Maintenance
  class NoCollectionTask < MaintenanceTasks::Task
    no_collection
    attribute :arg, :string
    validates :arg, presence: true

    def process
      SomeAsyncJob.perform_later(arg)
    end
  end
end
このスクラップは17日前にクローズされました