From cd225643ce526d4d7c123f033c6ccdc151cf2750 Mon Sep 17 00:00:00 2001 From: fumimowdan Date: Mon, 23 Oct 2023 16:43:38 +0100 Subject: [PATCH] Wrap Urn method `next` in fiber block To protect against FiberError --- app/models/urn.rb | 25 ++++++++++++++++++++----- app/services/submit_form.rb | 1 + config/initializers/urn.rb | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/models/urn.rb b/app/models/urn.rb index 9a2a31ad..94c17f22 100644 --- a/app/models/urn.rb +++ b/app/models/urn.rb @@ -27,10 +27,11 @@ def initialize teacher: "TE", salaried_trainee: "ST", }.with_indifferent_access - @default_urns = ->(_) { [] } + @default_urns = { teacher: [], salaried_trainee: [] }.with_indifferent_access + @default_existing_urns = -> { [] } end - attr_writer :prefix, :codes, :max_suffix, :seeds, :urns, :padding_size + attr_writer :prefix, :codes, :max_suffix, :seeds, :existing_urns, :padding_size def prefix @prefix || @default_prefix @@ -53,7 +54,11 @@ def seeds end def urns - @urns || @default_urns + (@urns || @default_urns).with_indifferent_access + end + + def existing_urns + @existing_urns || @default_existing_urns end end @@ -69,11 +74,21 @@ def config end def next(route) - routes[route].next + Fiber.new { routes[route].next }.resume rescue KeyError raise(ArgumentError, "Invalid route: #{route}, must be one of #{config.codes.keys}") end + def load_existing_urns + return @urns if @urns + + data = config.existing_urns.call + @urns = data.each_with_object(config.urns) do |(route, urn), hash| + hash[route] << urn + hash + end + end + private def routes @@ -81,7 +96,7 @@ def routes hash[route] = urn_enumerator( config.codes.fetch(route), config.seeds.fetch(route, Random.new_seed), - config.urns.call(route), + config.urns.fetch(route), ) end end diff --git a/app/services/submit_form.rb b/app/services/submit_form.rb index a6ccb4d5..60b50442 100644 --- a/app/services/submit_form.rb +++ b/app/services/submit_form.rb @@ -27,6 +27,7 @@ def success? end def submit_form! + Urn.load_existing_urns create_application_records send_applicant_email @success = true diff --git a/config/initializers/urn.rb b/config/initializers/urn.rb index f9658c35..aa7533c8 100644 --- a/config/initializers/urn.rb +++ b/config/initializers/urn.rb @@ -3,5 +3,5 @@ Urn.configure do |c| c.prefix = "IRP" c.max_suffix = 99_999 - c.urns = ->(route) { Application.where(application_route: route).pluck(:urn) } + c.existing_urns = -> { Application.group(:application_route, :urn).pluck(:application_route, :urn) } end