prevent race conditions when creating archives

This commit is contained in:
Christophe Robillard 2021-04-27 18:57:13 +02:00
parent dfbe004122
commit 09870c918d
5 changed files with 23 additions and 13 deletions

View file

@ -3,6 +3,7 @@
# Table name: archives
#
# id :bigint not null, primary key
# key :text not null
# month :date
# status :string not null
# time_span_type :string not null
@ -56,4 +57,15 @@ class Archive < ApplicationRecord
"procedure-#{procedure.id}-mois-#{I18n.l(month, format: '%Y-%m')}.zip"
end
end
def self.find_or_create_archive(time_span_type, month, groupe_instructeurs)
create_with(groupe_instructeurs: groupe_instructeurs)
.create_or_find_by(time_span_type: time_span_type, month: month, key: generate_cache_key(groupe_instructeurs))
end
private
def self.generate_cache_key(groupe_instructeurs)
groupe_instructeurs.map(&:id).sort.join('-')
end
end

View file

@ -10,18 +10,7 @@ class ProcedureArchiveService
.groupe_instructeurs
.where(procedure: @procedure)
archive = Archive.for_groupe_instructeur(groupe_instructeurs).find_by(
time_span_type: type,
month: month
)
if archive.nil?
archive = Archive.create!(
content_type: type,
month: month,
groupe_instructeurs: groupe_instructeurs
)
end
archive
Archive.find_or_create_archive(type, month, groupe_instructeurs)
end
def collect_files_archive(archive, instructeur)

View file

@ -0,0 +1,6 @@
class AddKeyToArchives < ActiveRecord::Migration[6.1]
def change
add_column :archives, :key, :text, null: false
add_index :archives, [:key, :time_span_type, :month], unique: true
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_04_27_112642) do
ActiveRecord::Schema.define(version: 2021_04_27_124500) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -87,6 +87,8 @@ ActiveRecord::Schema.define(version: 2021_04_27_112642) do
t.string "time_span_type", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.text "key", null: false
t.index ["key", "time_span_type", "month"], name: "index_archives_on_key_and_time_span_type_and_month", unique: true
end
create_table "archives_groupe_instructeurs", force: :cascade do |t|

View file

@ -2,6 +2,7 @@ FactoryBot.define do
factory :archive do
time_span_type { 'everything' }
groupe_instructeurs { [association(:groupe_instructeur)] }
key { 'unique-key' }
trait :pending do
status { 'pending' }