Skip to content

Commit

Permalink
Allow batch jobs to be instances
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
jpcamara committed Feb 8, 2024
1 parent ec2cf15 commit 6495eb3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 20 deletions.
38 changes: 22 additions & 16 deletions app/models/solid_queue/job_batch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class JobBatch < Record
belongs_to :job, foreign_key: :job_id, optional: true
has_many :jobs, foreign_key: :batch_id

serialize :on_finish_active_job, coder: JSON
serialize :on_success_active_job, coder: JSON

scope :incomplete, -> {
where(finished_at: nil).where("changed_at IS NOT NULL OR last_changed_at < ?", 1.hour.ago)
}
Expand All @@ -21,7 +24,7 @@ def enqueue(attributes = {})
transaction do
job_batch = create!(batch_attributes(attributes))
ActiveSupport::IsolatedExecutionState[:current_batch_id] = job_batch.id
yield
yield job_batch
end

job_batch
Expand All @@ -40,20 +43,22 @@ def dispatch_finished_batches
private

def batch_attributes(attributes)
attributes = case attributes
in { on_finish: on_finish_klass }
attributes.merge(
job_class: on_finish_klass,
completion_type: "success"
)
in { on_success: on_success_klass }
attributes.merge(
job_class: on_success_klass,
completion_type: "success"
)
on_finish_klass = attributes.delete(:on_finish)
on_success_klass = attributes.delete(:on_success)

if on_finish_klass.present?
attributes[:on_finish_active_job] = as_active_job(on_finish_klass).serialize
end

if on_success_klass.present?
attributes[:on_success_active_job] = as_active_job(on_success_klass).serialize
end

attributes.except(:on_finish, :on_success)
attributes
end

def as_active_job(active_job_klass)
active_job_klass.is_a?(ActiveJob::Base) ? active_job_klass : active_job_klass.new
end
end

Expand All @@ -74,9 +79,10 @@ def finish

attrs = {}

if job_class.present?
job_klass = job_class.constantize
active_job = job_klass.perform_later(self)
if on_finish_active_job.present?
active_job = ActiveJob::Base.deserialize(on_finish_active_job)
active_job.send(:deserialize_arguments_if_needed)
ActiveJob.perform_all_later([active_job])
attrs[:job] = Job.find_by(active_job_id: active_job.job_id)
end

Expand Down
4 changes: 2 additions & 2 deletions db/migrate/20240131013203_create_solid_queue_batch_table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ class CreateSolidQueueBatchTable < ActiveRecord::Migration[7.1]
def change
create_table :solid_queue_job_batches do |t|
t.references :job, index: { unique: true }
t.string :job_class
t.string :completion_type
t.string :on_finish_active_job
t.string :on_success_active_job
t.datetime :finished_at
t.datetime :changed_at
t.datetime :last_changed_at
Expand Down
4 changes: 2 additions & 2 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@

create_table "solid_queue_job_batches", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "job_id"
t.string "job_class"
t.string "completion_type"
t.string "on_finish_active_job"
t.string "on_success_active_job"
t.datetime "finished_at"
t.datetime "changed_at"
t.datetime "last_changed_at"
Expand Down

0 comments on commit 6495eb3

Please sign in to comment.