Script de rebake lento para evitar sobrecarregar seu servidor

Então tive que ir para o ar sem esperar que todo o rebake terminasse. Após ir para o ar, não pude executar o rebake, pois isso derrubaria o servidor. Eu poderia executar o rebake na fila padrão, pois isso atrasaria todos os outros processos, como notificações.

Então usei este script para enfileirar todas as tarefas de rebake na fila sidekiq de prioridade ultrabaixa. Compartilhando aqui caso mais alguém precise.

# slow_rebake_resumer_ultralow.rb
# Retoma o enfileiramento de jobs de rebake a partir de um ponto específico e os envia
# diretamente para a fila de prioridade :ultra_low.
# execute dentro do container com -> rails runner slow_rebake_resumer_ultralow.rb

# --- Configuração ---
BATCH_SIZE = 500
SLEEP_DURATION = 5
# --- Ponto de partida da sua última atualização ---
last_processed_id = 1952526 
# --------------------

start_time = Time.now
total_posts = Post.count

puts "Retomando e enfileirando jobs de rebake para #{total_posts} posts na fila :ultra_low..."
puts "Começando após o post ID #{last_processed_id}."
puts "---"

loop do
  # Encontra eficientemente o próximo lote de posts a serem processados
  posts_to_enqueue = Post.where("id "> ?", last_processed_id).order(id: :asc).limit(BATCH_SIZE)

  # Sai do loop se não houver mais posts
  break if posts_to_enqueue.empty?

  posts_to_enqueue.each do |post|
    begin
      # Define todas as opções em um único hash, incluindo a fila de destino
      options = {
        post_id: post.id,
        cook: true,
        bypass_bump: true,
        queue: :ultra_low
      }

      # Enfileira o job com a sintaxe correta e verificada
      Jobs.enqueue(:process_post, options)

    rescue ="> e"
      puts "!!! ERRO ao enfileirar job para o post ID #{post.id}: #{e.message}"
    end
  end

  # Atualiza nossa posição para o último ID de post no lote atual
  last_processed_id = posts_to_enqueue.last.id
  
  # Obtém uma contagem mais precisa para o relatório de progresso
  enqueued_count = Post.where("id "> = ?", last_processed_id).count

  # --- Relatório de Progresso ---
  percentage = (enqueued_count.to_f / total_posts * 100).round(2)
  elapsed_minutes = ((Time.now - start_time) / 60).round(2)

  puts "Enfileirado até o post ID #{last_processed_id}. Total enfileirado: ~#{enqueued_count} / #{total_posts} (#{percentage}%)"
  puts "Tempo decorrido (esta sessão): #{elapsed_minutes} minutos."
  puts "Jobs estão sendo enviados para a fila :ultra_low."

  # Pausa entre os lotes para manter a carga baixa
  if enqueued_count < total_posts
    puts "Dormindo por #{SLEEP_DURATION} segundos..."
    sleep(SLEEP_DURATION)
    puts "---"
  end
end

puts "\nTodos os jobs de rebake restantes foram enfileirados com sucesso na fila :ultra_low!"

3 curtidas

Tenho quase certeza de que já existe um processo rodando o tempo todo que faz praticamente a mesma coisa e que é mencionado pelo script de restauração, mas talvez você tenha executado a migração no servidor ativo e não a tenha visto…

Sim, existe. Eu não executei o script de migração padrão. Postarei mais sobre isso depois que os usuários pararem de reclamar da rolagem infinita e da experiência de usuário confusa no Discourse. :upside_down_face:

Mas, em geral, também pode ser necessário um “rebake” completo, como alterar o domínio, fazer algumas substituições, etc.

Desculpe por reativar o post, estou em uma situação semelhante com meu Discourse.

Alguma dica sobre como executar esse script?

Onde criar o script e como chamá-lo?

Obrigado antecipadamente

Crie um arquivo slow_rebake_resumer_ultralow.rb no diretório tmp dentro do diretório shared e cole todo o código nele.

Em seguida, execute esse arquivo uma vez dentro do contêiner com rails runner slow_rebake_resumer_ultralow.rb

Observe o progresso em yousite.com/sidekiq

1 curtida