Estoy usando Sidekiq para trabajos retrasados con sidekiq-status y sidekiq-ent . Creé un trabajador que es responsable de actualizar el estado de minor a false cuando el usuario es adult y tiene minor: true . Este trabajador debe ser despedido todos los días a la medianoche ET. Como abajo:
#initializers/sidekiq.rb config.periodic do |mgr| # every day between midnight 0 5 * * * mgr.register("0 5 * * *", MinorWorker) end #app/workers/minor_worker.rb class MinorWorker include Sidekiq::Worker def perform User.adults.where(minor: true).remove_minor_status rescue => e Rails.logger.error("Unable to update minor field. Exception: #{e.message} : #{e.backtrace.join('\n')}") end end #models/user.rb class User < ApplicationRecord scope :adults, -> { where('date_of_birth <= ?', 18.years.ago) } def self.remove_minor_status update(minor: false) end end No, quiero verificar esto en mi máquina local; para hacerlo, estoy usando gem 'timecop' para viajar en el tiempo:
#application.rb config.time_zone = 'Eastern Time (US & Canada)' #config/environments/development.rb config.after_initialize do t = Time.local(2021, 12, 21, 23, 59, 0) Timecop.travel(t) end Después de activar sidekiq por bundle exec sidekiq y bundle exec rails s , estoy esperando un minuto y veo que aparece el trabajador:
2021-12-21T22:59:00.130Z 25711 TID-ovvzr9828 INFO: Managing 3 periodic jobs 2021-12-21T23:00:00.009Z 25711 TID-ovw69k4ao INFO: Enqueued periodic job SettlementWorker with JID ddab15264f81e0b417e7dd83 for 2021-12-22 00:00:00 +0100 2021-12-21T23:00:00.011Z 25711 TID-ovw69k4ao INFO: Enqueued periodic job MinorWorker with JID 0bcd6b76d6ee4ff9e7850b35 for 2021-12-22 00:00:00 +0100 Pero no hizo nada, el estado menor del usuario todavía está establecido en minor: true :
2.4.5 :002 > User.last.date_of_birth => Mon, 22 Dec 2003 2.4.5 :001 > User.last.minor => true¿Me he perdido algo?
EDITAR
Debo agregar que cuando trato de llamar a este trabajador sobre rails c , todo funciona bien. Incluso tengo una prueba RSpec que también pasa:
RSpec.describe MinorWorker, type: :worker do subject(:perform) { described_class.new.perform } context 'when User has minor status' do let(:user1) { create(:user, minor: true) } it 'removes minor status' do expect { perform }.to change { user1.reload.minor }.from(true).to(false) end context 'when user is adult' do let(:registrant2) { create(:registrant) } it 'not change minor status' do expect(registrant2.reload.minor).to eq(false) end end end endDado que esta es la update del método de clase, no funcionará
def self.remove_minor_status update(minor: false) endUtilice #update_all
def self.remove_minor_status update_all(minor: false) endAdemás, creo que es una buena práctica tener algunos casos de prueba para garantizar el funcionamiento de los métodos.
A partir de ahora, puede probar este método desde rails console y verificar si realmente funcionan.
test "update minor status" do user = User.create(date_of_birth: 19.years.ago, minor: true) User.adults.where(minor: true).remove_minor_status assert_equal user.reload.minor, false endCreo que debe hacer update_all o update cada registro por sí mismo, así:
User.adults.where(minor: true).update_all(minor: false)o
class MinorWorker include Sidekiq::Worker def perform users = User.adults.where(minor: true) users.each { |user| user.remove_minor_status } rescue => e Rails.logger.error("Unable to update minor field. Exception: #{e.message} : #{e.backtrace.join('\n')}") end end ¡También puede considerar cambiar de update a update! por lo que arroja un error si su rescue no lo detecta en el trabajo:
def self.remove_minor_status update!(minor: false) end