Il task rake del plugin si esegue più volte - cosa stiamo perdendo?

Sto aggiungendo un rake task al plugin docker_manager ma scopro che il task viene eseguito due volte quando lo richiamo. Nella sua forma più semplice, posso aggiungere testing.rake a lib/tasks con i seguenti contenuti:

# frozen_string_literal: true

desc "A test"
task "docker_manager:test" do
  puts "test"
end

Con questo risultato:

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

Ho confermato che questo non è un problema generale con i task nei plugin aggiungendo lo stesso file rake al plugin poll con questo risultato:

/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
test

Non sono ancora riuscito a trovare nulla di ovvio nei due plugin che potrebbe impedire/causare questo, quindi spero che qualcuno possa offrire suggerimenti su cosa potrebbe impedire questo in poll o causarlo in docker_manager.

3 Mi Piace

Hai risolto questo problema?

Sto riscontrando un problema simile:

Se creo un rake task in un plugin, ad esempio: lib/tasks/test.rake

con contenuto

desc "conta i post"
task "test_rake:test" => :environment do
  puts "Il numero di post in questo forum è #{Post.count}"
end

e eseguo: rake test_rake:test

L’output mi sorprende:

Il numero di post in questo forum è 366
Il numero di post in questo forum è 366
Il numero di post in questo forum è 366

Sto commettendo qualche errore, ne sono sicuro, ma non so quale?

Perché viene eseguito più di una volta e come posso fermarlo?

Ho un problema simile in produzione che è, ovviamente, una preoccupazione più seria.

2 Mi Piace

OK, sono riuscito a ridurre il task a soli due cicli rimuovendo il task dal blocco di inizializzazione. A quanto pare è sufficiente inserirlo in /lib/tasks senza doverlo caricare.

Questo mi ha portato a 1 ripetizione (ora per un totale di 2!) :sweat_smile:

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

Questo ripete semplicemente l’esperienza dell’OP.

2 Mi Piace

Purtroppo no. Inizialmente avevo ipotizzato che fosse qualcosa nel core a causarne il caricamento due volte, ma vedendo che veniva eseguito solo una volta quando aggiunto al plugin poll sembrava confutarlo.

Ora l’ho dimenticato, ma penso che l’uso di --trace potrebbe anche mostrare che viene caricato solo una volta. Potrei sbagliarmi, ma se ricordo bene, le righe invoke e/o execute appariranno due volte se viene caricato due volte.

Non sono riuscito a trovare differenze tra docker_manager e poll o qualcosa nel core che spiegasse questa differenza di comportamento, e avevo praticamente rinunciato quando ho fatto il post.

1 Mi Piace

Potrei essere un po’ in ritardo :slight_smile:

Sto riscontrando lo stesso problema in un nuovo plugin e ho cercato un po’. Sembra che questo problema colpisca anche altri plugin (ad esempio: il plugin di chat ufficiale), ma ho trovato una soluzione funzionante per evitare che i task vengano registrati più volte:

# Cancella qualsiasi registrazione precedente
task('import_json:preview').clear

# Definizione del task
desc 'Anteprima delle modifiche che verrebbero applicate da import_json'
task 'import_json:preview', [:file_path] => :environment do |_task, args|
  puts "Hello world!"
end

Cancellare dopo la descrizione del task impedirà che il task venga elencato con rake --tasks, quindi deve essere cancellato prima.

3 Mi Piace

Ciò significa che si ottiene lo stesso risultato aggiungendo un’attività ad esso o che un’attività già esistente nel plugin ha questo comportamento?

Grazie per le informazioni! Sembra un po’ una soluzione di fortuna doverla cancellare, ma è sicuramente un utile rimedio.

Segnerò il tuo post come soluzione per comodità degli altri. Speriamo che la causa più ampia possa ancora essere identificata, immagino che la domanda diventi: perché le attività vengono registrate due volte in alcuni plugin e non in altri?

Questo significa che si ottiene lo stesso risultato aggiungendo un task o che un task già esistente nel plugin ha questo comportamento?

Mentre cercavo di capire perché i task che ho sviluppato nel mio plugin venivano eseguiti due volte, ho testato un task esistente nel plugin Chat e anche questo è stato eseguito due volte.

Ho testato anche alcuni task di altri plugin ma non ricordo quali. Alcuni venivano eseguiti una volta ma non c’era nulla di ovvio nella differenza di implementazione.

Forse c’è qualcosa da fare con l’autoloading?

Su un plugin nuovo, il motore contiene questa riga:

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

Se non carico automaticamente lib ma lib/some_path per evitare di caricare automaticamente lib/tasks, sembra meglio, ma lo svantaggio è che interrompe l’autoloading (mi sono fermato qui). Il che potrebbe portare ad avere un mucchio di istruzioni require_relative per compensare…

2 Mi Piace

Sembra certamente plausibile che se esiste già un meccanismo per caricare i task, questi potrebbero essere caricati una seconda volta.

Mi chiedo se l’uso di uno dei seguenti possa risolvere il problema (penso che propenderei per quest’ultimo poiché non conosco quali effetti collaterali potrebbero esserci al caricamento automatico una volta):

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.