active-job-coder について
Rails Active Job のジョブを設計・リファクタリングするコーディングエージェント向けのスキルです。キュー、再試行、並行制御、スケジュール、冪等性を扱います。
主な機能
- 01単一責任に基づくジョブ設計
- 02IDを渡して最新レコードを取得
- 03キューと優先度の設定
- 04再試行、破棄、エラー処理の設定
- 05並行制御とジョブの予約
活用シーン
- 01メール配信や注文処理ジョブの作成
- 02外部 API 呼び出しの再試行設定
- 03リマインダーの予約と一括キュー登録
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ majesticlabs-dev/ majestic-marketplace --skill active-job-coderインストール後、Claude Code で/active-job-coderを入力して読み込まれたか確認します。
詳細
Active Job コーディング
ジョブ設計の原則
1. 単一責任
# Good: Focused job
class SendWelcomeEmailJob < ApplicationJob
queue_as :default
def perform(user)
UserMailer.welcome(user).deliver_now
end
end
2. オブジェクトではなく ID を渡す
# Good: Pass identifiers
class ProcessOrderJob < ApplicationJob
def perform(order_id)
order = Order.find(order_id)
# Process order
end
end
3. キューの設定
class CriticalNotificationJob < ApplicationJob
queue_as :critical
queue_with_priority 1 # Lower = higher priority
end
class ReportGenerationJob < ApplicationJob
queue_as :low_priority
queue_with_priority 50
end
エラー処理と再試行戦略
class ExternalApiJob < ApplicationJob
queue_as :default
retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 5
retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
discard_on ActiveJob::DeserializationError
def perform(record_id)
record = Record.find(record_id)
ExternalApi.sync(record)
end
end
カスタムエラー処理
class ImportantJob < ApplicationJob
rescue_from StandardError do |exception|
Rails.logger.error("Job failed: #{exception.message}")
ErrorNotifier.notify(exception, job: self.class.name)
raise # Re-raise to trigger retry
end
end
並行処理の制御(Solid Queue)
class ProcessUserDataJob < ApplicationJob
limits_concurrency key: ->(user_id) { user_id }, duration: 15.minutes
def perform(user_id)
user = User.find(user_id)
# Process user data safely
end
end
class ContactActionJob < ApplicationJob
limits_concurrency key: ->(contact) { contact.id },
duration: 10.minutes,
group: "ContactActions"
end
スケジューリングと遅延実行
SendReminderJob.perform_later(user) # Immediate
SendReminderJob.set(wait: 1.hour).perform_later(user) # Delayed
SendReminderJob.set(wait_until: Date.tomorrow.noon).perform_later(user) # Scheduled
# Bulk enqueue
ActiveJob.perform_all_later(users.map { |u| SendReminderJob.new(u.id) })
避けるべきアンチパターン
| アンチパターン | 問題 | 解決策 |
|---|---|---|
| 肥大化したジョブ | テストや保守が難しい | ロジックをモデルクラスに切り出す |
| オブジェクトのシリアライズ | コストが高く、データが古くなる | ID を渡し、最新のデータを取得する |
| 再試行戦略がない | 失敗が見過ごされる | バックオフを設定して retry_on を使用する |
| 同期呼び出し | リクエストをブロックする | 常に perform_later を使用する |
| 冪等性がない | 重複処理が発生する | 再実行可能なジョブを設計する |
| エラーを無視する | 失敗が見過ごされる | ログ記録を伴う rescue_from を使用する |
| モノリシックなステップ | 失敗後に再開できない | 状態を使用する Continuable パターンを使う |
出力形式
ジョブを作成またはリファクタリングする場合は、次を提示してください。
- ジョブクラス - ジョブの完全な実装
- キュー戦略 - 推奨するキューと優先度
- エラー処理 - 再試行と失敗への対処戦略
- テスト - テストケースの例
- 考慮事項 - 並行処理と冪等性に関する注意点
コメント
Markdown 対応