Skip to content

Commit b2f3aa5

Browse files
authored
Merge pull request #13303 from demarche-numerique/fix_race_condition_on_ocr
Tech: résoud un problème d'accès concurrents pour l'analyse OCR
2 parents 1fa2e35 + f7f8216 commit b2f3aa5

4 files changed

Lines changed: 30 additions & 5 deletions

File tree

app/controllers/champs/piece_justificative_controller.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ def attach_piece_justificative
3434
save_succeed = Attachment::PieceJustificativeService.attach_champ_pj(@champ, params[:blob_signed_id])
3535

3636
if save_succeed
37-
@champ.fetch_later! if @champ.has_async_external_data? && @champ.may_fetch_later?
38-
3937
@champ.update_timestamps
4038

4139
dossier = DossierPreloader.load_one(@champ.dossier, pj_template: true)

app/services/attachment/piece_justificative_service.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ def self.attach_champ_pj(champ, blob_signed_id)
1414
champ.reload(lock: true) # SELECT FOR UPDATE + clear association cache
1515
champ.updated_by = updated_by # keep record dirty so attach defers save to us
1616
champ.piece_justificative_file.attach(blob_signed_id)
17+
18+
# fetch_later should be called inside the transaction to avoid
19+
# race condition with processor_job
20+
champ.fetch_later if champ.has_async_external_data? && champ.may_fetch_later?
21+
1722
context = champ.public? ? :champs_public_value : :champs_private_value
1823
champ.save(context:)
1924
end

spec/controllers/champs/piece_justificative_controller_spec.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474

7575
before do
7676
allow_any_instance_of(Champs::PieceJustificativeChamp).to receive(:has_async_external_data?).and_return(true)
77-
expect_any_instance_of(Champs::PieceJustificativeChamp).to receive(:fetch_later!)
7877
end
7978

8079
it 'attach the file' do
@@ -84,6 +83,11 @@
8483
expect(champ.piece_justificative_file[0].filename).to eq('piece_justificative_0.pdf')
8584
end
8685

86+
it 'marks the champ waiting_for_job' do
87+
subject
88+
expect(champ.reload).to be_waiting_for_job
89+
end
90+
8791
it 'renders the attachment template as Javascript' do
8892
subject
8993
expect(response.status).to eq(200)
@@ -103,10 +107,10 @@
103107
champ.update_column(:external_state, :fetched)
104108
end
105109

106-
it 'does not call fetch_later!' do
107-
expect_any_instance_of(Champs::PieceJustificativeChamp).not_to receive(:fetch_later!)
110+
it 'does not transition the champ out of fetched' do
108111
subject
109112
expect(response.status).to eq(200)
113+
expect(champ.reload).to be_fetched
110114
end
111115
end
112116

spec/services/attachment/piece_justificative_service_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,23 @@
3434
expect(champ.reload.piece_justificative_file.count).to eq(2)
3535
end
3636
end
37+
38+
context 'with an OCR-compatible PJ (justificatif de domicile)' do
39+
let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :piece_justificative, nature: 'justificatif_domicile' }]) }
40+
41+
it 'transitions the champ to waiting_for_job in the same transaction' do
42+
described_class.attach_champ_pj(champ, blob_1.signed_id)
43+
44+
expect(champ.reload).to be_waiting_for_job
45+
end
46+
end
47+
48+
context 'with a non-OCR PJ' do
49+
it 'leaves the champ idle' do
50+
described_class.attach_champ_pj(champ, blob_1.signed_id)
51+
52+
expect(champ.reload).to be_idle
53+
end
54+
end
3755
end
3856
end

0 commit comments

Comments
 (0)