Skip to content

Commit 6495eb3

Browse files
committed
Allow batch jobs to be instances
* This means we can store the arguments and settings by letting the user do `BatchJob.new(arguments).set(options)` * Yield the batch in `enqueue` in case someone needs info from it * When you serialize then deserialize an activejob instance, the arguments are in the serialized_arguments field and can only be transferred over by the private method `deserialize_arguments_if_needed`. This is pretty janky, so there is probably something i'm missing * `perform_all_later` let's us do a perform_later even with instance, which does not seem to be possible on the instances themselves
1 parent ec2cf15 commit 6495eb3

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed

app/models/solid_queue/job_batch.rb

+22-16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ class JobBatch < Record
55
belongs_to :job, foreign_key: :job_id, optional: true
66
has_many :jobs, foreign_key: :batch_id
77

8+
serialize :on_finish_active_job, coder: JSON
9+
serialize :on_success_active_job, coder: JSON
10+
811
scope :incomplete, -> {
912
where(finished_at: nil).where("changed_at IS NOT NULL OR last_changed_at < ?", 1.hour.ago)
1013
}
@@ -21,7 +24,7 @@ def enqueue(attributes = {})
2124
transaction do
2225
job_batch = create!(batch_attributes(attributes))
2326
ActiveSupport::IsolatedExecutionState[:current_batch_id] = job_batch.id
24-
yield
27+
yield job_batch
2528
end
2629

2730
job_batch
@@ -40,20 +43,22 @@ def dispatch_finished_batches
4043
private
4144

4245
def batch_attributes(attributes)
43-
attributes = case attributes
44-
in { on_finish: on_finish_klass }
45-
attributes.merge(
46-
job_class: on_finish_klass,
47-
completion_type: "success"
48-
)
49-
in { on_success: on_success_klass }
50-
attributes.merge(
51-
job_class: on_success_klass,
52-
completion_type: "success"
53-
)
46+
on_finish_klass = attributes.delete(:on_finish)
47+
on_success_klass = attributes.delete(:on_success)
48+
49+
if on_finish_klass.present?
50+
attributes[:on_finish_active_job] = as_active_job(on_finish_klass).serialize
51+
end
52+
53+
if on_success_klass.present?
54+
attributes[:on_success_active_job] = as_active_job(on_success_klass).serialize
5455
end
5556

56-
attributes.except(:on_finish, :on_success)
57+
attributes
58+
end
59+
60+
def as_active_job(active_job_klass)
61+
active_job_klass.is_a?(ActiveJob::Base) ? active_job_klass : active_job_klass.new
5762
end
5863
end
5964

@@ -74,9 +79,10 @@ def finish
7479

7580
attrs = {}
7681

77-
if job_class.present?
78-
job_klass = job_class.constantize
79-
active_job = job_klass.perform_later(self)
82+
if on_finish_active_job.present?
83+
active_job = ActiveJob::Base.deserialize(on_finish_active_job)
84+
active_job.send(:deserialize_arguments_if_needed)
85+
ActiveJob.perform_all_later([active_job])
8086
attrs[:job] = Job.find_by(active_job_id: active_job.job_id)
8187
end
8288

db/migrate/20240131013203_create_solid_queue_batch_table.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ class CreateSolidQueueBatchTable < ActiveRecord::Migration[7.1]
22
def change
33
create_table :solid_queue_job_batches do |t|
44
t.references :job, index: { unique: true }
5-
t.string :job_class
6-
t.string :completion_type
5+
t.string :on_finish_active_job
6+
t.string :on_success_active_job
77
t.datetime :finished_at
88
t.datetime :changed_at
99
t.datetime :last_changed_at

test/dummy/db/schema.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848

4949
create_table "solid_queue_job_batches", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
5050
t.bigint "job_id"
51-
t.string "job_class"
52-
t.string "completion_type"
51+
t.string "on_finish_active_job"
52+
t.string "on_success_active_job"
5353
t.datetime "finished_at"
5454
t.datetime "changed_at"
5555
t.datetime "last_changed_at"

0 commit comments

Comments
 (0)