Tarefa rake do plugin executando várias vezes - o que estamos perdendo?

Estou adicionando uma tarefa rake ao plugin docker_manager, mas descobri que a tarefa está sendo executada duas vezes quando a invoco. Em sua forma mais simples, posso adicionar testing.rake a lib/tasks com o seguinte conteúdo:

# frozen_string_literal: true

desc "Um teste"
task "docker_manager:test" do
  puts "teste"
end

Com este resultado:

/var/www/discourse# rake docker_manager:test --trace
** Invoke docker_manager:test (first_time)
** Execute docker_manager:test
teste
teste

Confirmei que este não é um problema geral com tarefas em plugins, adicionando o mesmo arquivo rake ao plugin poll com este resultado:

/var/www/discourse# mv plugins/docker_manager/lib/tasks/testing.rake plugins/poll/lib/tasks/
/var/www/discourse# rake docker_manager:test --trace
** Invoke docker_manager:test (first_time)
** Execute docker_manager:test
teste

Ainda não consegui encontrar nada óbvio nos dois plugins que possa estar impedindo/causando isso, então espero que alguém possa oferecer sugestões sobre o que pode estar impedindo isso em poll ou causando isso em docker_manager.

3 curtidas

Você resolveu isso?

Estou tendo um problema semelhante:

Se eu criar uma tarefa rake em um plugin, por exemplo: lib/tasks/test.rake

com o conteúdo

desc "count posts"
task "test_rake:test" => :environment do
  puts "Number of posts on this forum is #{Post.count}"
end

e executar: rake test_rake:test

A saída é surpreendente para mim:

Number of posts on this forum is 366
Number of posts on this forum is 366
Number of posts on this forum is 366

Tenho certeza de que estou cometendo algum tipo de erro, mas não sei qual?

Por que isso está sendo executado mais de uma vez e como pará-lo?

Tenho um problema semelhante em Produção que, claro, é uma preocupação mais séria.

2 curtidas

OK, consegui reduzir a tarefa para rodar apenas duas vezes ao remover a tarefa de ser carregada no bloco initialize. Aparentemente, basta colocá-la em /lib/tasks sem precisar carregá-la.

Isso me reduziu a 1 repetição (agora para um total de 2!) :sweat_smile:

Number of posts on this forum is 366
Number of posts on this forum is 366

Isso apenas repete a experiência do OP.

2 curtidas

Infelizmente não. Inicialmente, eu presumi que era algo no núcleo que o estava fazendo carregar duas vezes, mas vendo que ele só rodava uma vez quando adicionado ao plugin de enquete parecia refutar isso.

Eu meio que esqueci agora, mas acho que usar --trace também pode mostrar que ele só carrega uma vez. Posso estar errado, mas se bem me lembro, as linhas invoke e/ou execute aparecerão duas vezes se ele for carregado duas vezes.

Não consegui encontrar nenhuma diferença entre docker_manager e poll ou qualquer coisa no núcleo que explicasse essa diferença de comportamento, e basicamente desisti quando fiz a postagem.

1 curtida

Posso estar um pouco atrasado :slight_smile:

Estou encontrando o mesmo problema em um novo plugin e pesquisei um pouco. Parece que esse problema afeta outros plugins também (por exemplo: o plugin oficial de chat), mas encontrei uma solução funcional para evitar que as tarefas sejam registradas várias vezes:

# Limpa qualquer registro anterior
task('import_json:preview').clear

# Definição da tarefa
desc 'Previews changes which would be applied by import_json'
task 'import_json:preview', [:file_path] => :environment do |_task, args|
  puts "Hello world!"
end

Limpar após a descrição da tarefa impedirá que a tarefa seja listada com rake --tasks, então ela deve ser limpa antes.

3 curtidas

Isso significa que você obtém o mesmo resultado ao adicionar uma tarefa a ele ou que uma tarefa já existente no plugin tem esse comportamento?

Obrigado pela informação! Parece um pouco “hacky” ter que limpá-lo, mas certamente é uma solução alternativa útil.

Marcarei sua postagem como a solução para conveniência de outros. Espero que a causa mais ampla ainda possa ser identificada, acho que a questão se torna: por que as tarefas são registradas duas vezes em alguns plugins e não em outros?

Isso significa que você obtém o mesmo resultado ao adicionar uma tarefa a ele ou que uma tarefa já existente no plugin tem esse comportamento?

Ao tentar entender por que as tarefas que desenvolvi em meu próprio plugin foram executadas duas vezes, testei uma tarefa existente no plugin Chat e ela também foi executada duas vezes.

Testei algumas tarefas de outros plugins também, mas não consigo me lembrar de quais. Algumas estavam executando uma vez, mas não havia nada óbvio sobre a diferença de implementação.

Talvez haja algo a ver com o autoloading?

Em um plugin novo, o engine contém esta linha:

config.autoload_paths << File.join(config.root, "lib")

Se eu não carregar automaticamente lib, mas lib/some_path para evitar carregar automaticamente lib/tasks, parece melhor, mas a desvantagem é que isso quebra o autoloading (parei aqui). O que pode levar a ter um monte de instruções require_relative para compensar…

2 curtidas

Certamente parece plausível que, se já houver um mecanismo para carregar as tarefas, isso possa fazer com que elas sejam carregadas uma segunda vez.

Eu me pergunto se usar um dos seguintes resolveria isso (acho que tenderia para o último, já que não sei quais efeitos colaterais podem haver ao fazer autoload uma vez):

config.autoload_once_paths << File.join(config.root, "lib")
config.autoload_lib(ignore: %w( tasks ))

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.