poc(batch_operation): track dossier processed safely
This commit is contained in:
parent
7a51ecec5d
commit
4266ab93c5
3 changed files with 26 additions and 13 deletions
|
@ -5,21 +5,11 @@ class BatchOperationProcessOneJob < ApplicationJob
|
|||
success = true
|
||||
begin
|
||||
batch_operation.process_one(dossier)
|
||||
dossier.update(batch_operation: nil)
|
||||
rescue => error
|
||||
success = false
|
||||
raise error
|
||||
ensure
|
||||
batch_operation.reload # reload before deciding if it has been finished
|
||||
batch_operation.run_at = Time.zone.now if batch_operation.called_for_first_time?
|
||||
batch_operation.finished_at = Time.zone.now if batch_operation.called_for_last_time?
|
||||
if success # beware to this one, will be refactored for stronger atomicity
|
||||
batch_operation.success_dossier_ids.push(dossier.id)
|
||||
batch_operation.failed_dossier_ids = batch_operation.failed_dossier_ids.reject { |d| d.dossier.id }
|
||||
else
|
||||
batch_operation.failed_dossier_ids.push(dossier.id)
|
||||
end
|
||||
batch_operation.save!
|
||||
batch_operation.track_dossier_processed(success, dossier)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,29 @@ class BatchOperation < ApplicationRecord
|
|||
.map { |dossier| BatchOperationProcessOneJob.perform_later(self, dossier) }
|
||||
end
|
||||
|
||||
def track_dossier_processed(success, dossier)
|
||||
transaction do
|
||||
dossier.update(batch_operation: nil)
|
||||
reload
|
||||
manager = Arel::UpdateManager.new.table(arel_table).where(arel_table[:id].eq(id))
|
||||
values = []
|
||||
values.push([arel_table[:run_at], Time.zone.now]) if called_for_first_time?
|
||||
values.push([arel_table[:finished_at], Time.zone.now]) if called_for_last_time?
|
||||
if success
|
||||
values.push([arel_table[:success_dossier_ids],Arel::Nodes::NamedFunction.new('array_append', [arel_table[:success_dossier_ids], dossier.id])])
|
||||
values.push([arel_table[:failed_dossier_ids], Arel::Nodes::NamedFunction.new('array_remove', [arel_table[:failed_dossier_ids], dossier.id])])
|
||||
else
|
||||
values.push([arel_table[:failed_dossier_ids], Arel::Nodes::NamedFunction.new('array_append', [arel_table[:failed_dossier_ids], dossier.id])])
|
||||
end
|
||||
manager.set(values)
|
||||
ActiveRecord::Base.connection.update(manager.to_sql)
|
||||
end
|
||||
end
|
||||
|
||||
def arel_table
|
||||
BatchOperation.arel_table
|
||||
end
|
||||
|
||||
def process_one(dossier)
|
||||
case operation
|
||||
when BatchOperation.operations.fetch(:archiver)
|
||||
|
|
|
@ -25,7 +25,7 @@ describe BatchOperationProcessOneJob, type: :job do
|
|||
context 'when it succeed' do
|
||||
it 'pushes dossier_job id to batch_operation.success_dossier_ids' do
|
||||
expect { subject.perform_now }
|
||||
.to change { batch_operation.success_dossier_ids }
|
||||
.to change { batch_operation.reload.success_dossier_ids }
|
||||
.from([])
|
||||
.to([dossier_job.id])
|
||||
end
|
||||
|
@ -44,7 +44,7 @@ describe BatchOperationProcessOneJob, type: :job do
|
|||
run_at = 2.minutes.ago
|
||||
Timecop.freeze(run_at) do
|
||||
expect { subject.perform_now }
|
||||
.to change { batch_operation.run_at }
|
||||
.to change { batch_operation.reload.run_at }
|
||||
.from(nil)
|
||||
.to(run_at)
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue