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

Store canonical recurring tasks in the DB #272

Merged
merged 11 commits into from
Aug 7, 2024
Next Next commit
Convert recurring tasks into Active Records
So we can persist them in the DB and support dynamic tasks, more complex
serialized arguments and enqueuing them on-demand from Mission Control
more easily.
rosa committed Aug 6, 2024
commit 7e2b5d1872c6b04904a9714ddbbae5b909ff8032
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
require "fugit"

module SolidQueue
class Dispatcher::RecurringTask
class RecurringTask < Record
serialize :arguments, coder: JSON

class << self
def wrap(args)
args.is_a?(self) ? args : from_configuration(args.first, **args.second)
end

def from_configuration(key, **options)
new(key, class_name: options[:class], schedule: options[:schedule], arguments: options[:args])
new(key: key, class_name: options[:class], schedule: options[:schedule], arguments: options[:args] || [])
end
end

attr_reader :key, :schedule, :class_name, :arguments

def initialize(key, class_name:, schedule:, arguments: nil)
@key = key
@class_name = class_name
@schedule = schedule
@arguments = Array(arguments)
end

def delay_from_now
[ (next_time - Time.current).to_f, 0 ].max
end
12 changes: 12 additions & 0 deletions db/migrate/20240719134516_create_recurring_tasks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class CreateRecurringTasks < ActiveRecord::Migration[7.1]
def change
create_table :solid_queue_recurring_tasks do |t|
t.string :key, null: false, index: { unique: true }
t.string :schedule, null: false
t.string :class_name, null: false
t.text :arguments

t.timestamps
end
end
end
2 changes: 1 addition & 1 deletion lib/solid_queue/configuration.rb
Original file line number Diff line number Diff line change
@@ -75,7 +75,7 @@ def options_from_raw_config(key, defaults)

def parse_recurring_tasks(tasks)
Array(tasks).map do |id, options|
Dispatcher::RecurringTask.from_configuration(id, **options)
RecurringTask.from_configuration(id, **options)
end.select(&:valid?)
end

2 changes: 1 addition & 1 deletion lib/solid_queue/dispatcher/recurring_schedule.rb
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ class Dispatcher::RecurringSchedule
attr_reader :configured_tasks, :scheduled_tasks

def initialize(tasks)
@configured_tasks = Array(tasks).map { |task| Dispatcher::RecurringTask.wrap(task) }
@configured_tasks = Array(tasks).map { |task| SolidQueue::RecurringTask.wrap(task) }
@scheduled_tasks = Concurrent::Hash.new
end

12 changes: 11 additions & 1 deletion test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
@@ -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_02_18_110712) do
ActiveRecord::Schema[7.1].define(version: 2024_07_19_134516) do
create_table "job_results", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "queue_name"
t.string "status"
@@ -101,6 +101,16 @@
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", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "key", null: false
t.string "schedule", null: false
t.string "class_name", null: false
t.text "arguments"
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
end

create_table "solid_queue_scheduled_executions", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "job_id", null: false
t.string "queue_name", null: false
2 changes: 1 addition & 1 deletion test/integration/instrumentation_test.rb
Original file line number Diff line number Diff line change
@@ -289,7 +289,7 @@ class InstrumentationTest < ActiveSupport::TestCase
assert events.size >= 1
event = events.last

assert_event event, "enqueue_recurring_task", task: :example_task, active_job_id: SolidQueue::Job.last.active_job_id
assert_event event, "enqueue_recurring_task", task: "example_task", active_job_id: SolidQueue::Job.last.active_job_id
assert event.last[:at].present?
assert_nil event.last[:other_adapter]
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "test_helper"

class RecurringTaskTest < ActiveSupport::TestCase
class SolidQueue::RecurringTaskTest < ActiveSupport::TestCase
class JobWithoutArguments < ApplicationJob
def perform
JobBuffer.add "job_without_arguments"
@@ -130,6 +130,6 @@ def enqueue_and_assert_performed_with_result(task, result)
end

def recurring_task_with(class_name:, schedule: "every hour", args: nil)
SolidQueue::Dispatcher::RecurringTask.from_configuration("task-id", class: "RecurringTaskTest::#{class_name}", schedule: schedule, args: args)
SolidQueue::RecurringTask.from_configuration("task-id", class: "SolidQueue::RecurringTaskTest::#{class_name}", schedule: schedule, args: args)
end
end