diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index d221628e..20ce5bad 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -72,7 +72,8 @@ class SitesController < ApplicationController authorize site # XXX: Convertir en una máquina de estados? - DeployJob.perform_async site.id if site.enqueue! + site.enqueue! + DeployJob.perform_async site.id redirect_to site_posts_path(site, locale: site.default_locale) end diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 98e474ac..f1ceca9e 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -8,13 +8,20 @@ class DeployJob < ApplicationJob def perform(site, notify = true) ActiveRecord::Base.connection_pool.with_connection do @site = Site.find(site) - @site.update_attribute :status, 'building' + + # Si ya hay una tarea corriendo, aplazar esta + if @site.building? + DeployJob.perform_in(60, site, notify) + return + end + + @site.update status: 'building' # Asegurarse que DeployLocal sea el primero! @deployed = { deploy_local: deploy_locally } # No es opcional unless @deployed[:deploy_local] - @site.update_attribute :status, 'waiting' + @site.update status: 'waiting' notify_usuaries if notify # Hacer fallar la tarea @@ -23,7 +30,7 @@ class DeployJob < ApplicationJob deploy_others notify_usuaries if notify - @site.update_attribute :status, 'waiting' + @site.update status: 'waiting' end end # rubocop:enable Metrics/MethodLength diff --git a/app/models/site.rb b/app/models/site.rb index 901d70c6..a4349f57 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -303,14 +303,25 @@ class Site < ApplicationRecord # Poner en la cola de compilación def enqueue! - !enqueued? && update_attribute(:status, 'enqueued') + update(status: 'enqueued') if waiting? end # Está en la cola de compilación? + # + # TODO: definir todos estos métodos dinámicamente, aunque todavía no + # tenemos una máquina de estados propiamente dicha. def enqueued? status == 'enqueued' end + def waiting? + status == 'waiting' + end + + def building? + status == 'building' + end + # Cargar el sitio Jekyll # # TODO: En lugar de leer todo junto de una vez, extraer la carga de diff --git a/test/controllers/sites_controller_test.rb b/test/controllers/sites_controller_test.rb index 5f67092a..a7e2f68b 100644 --- a/test/controllers/sites_controller_test.rb +++ b/test/controllers/sites_controller_test.rb @@ -102,6 +102,13 @@ class SitesControllerTest < ActionDispatch::IntegrationTest 'index.html')) end + test 'no se pueden encolar varias veces seguidas' do + assert_enqueued_jobs 2 do + post site_enqueue_url(@site), headers: @authorization + post site_enqueue_url(@site), headers: @authorization + end + end + test 'se pueden actualizar' do name = SecureRandom.hex design = Design.all.where.not(id: @site.design_id).sample