Plugin rake taskが複数回実行される - 何を見落としているのか?

docker_manager プラグインに rake タスクを追加していますが、呼び出すとタスクが 2 回実行されてしまいます。最も簡単な形式では、testing.rakelib/tasks に次のような内容で追加できます。

# frozen_string_literal: true

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

これにより、次のようになります。

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

プラグイン内のタスク全般の問題ではないことを、同じ rake ファイルを poll プラグインに追加して確認しました。結果は次のとおりです。

/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

poll でこれを防いでいる、または docker_manager でこれを引き起こしている可能性のある、2 つのプラグインの明白な点はまだ見つけられていません。そのため、誰かが poll でこれを防いでいる、または docker_manager でこれを引き起こしている可能性のあるものについて提案を提供してくれることを願っています。

「いいね!」 3

これを解決しましたか?

同様の問題が発生しています。

プラグインに lib/tasks/test.rake のような Rake タスクを作成した場合、

内容が次のようになっている場合:

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

そして rake test_rake:test を実行した場合:

驚くべき出力が得られます。

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

きっと何らかの間違いをしているのでしょうが、何が原因かわかりません。

なぜこれが複数回実行されるのか、そしてそれを止めるにはどうすればよいですか?

本番環境でも同様の問題が発生しており、もちろん、より深刻な懸念事項です。

「いいね!」 2

OK、タスクを初期化ブロックでのロードから 削除 することで、タスクを 2 回だけ実行するように減らすことができました。/lib/tasks に配置するだけでロードする必要はないようです。

これにより、繰り返しは 1 回になり、合計 2 回実行されるようになりました :sweat_smile:

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

これは OP の経験を繰り返すだけです。

「いいね!」 2

残念ながら解決していません。当初は、コアに原因があって2回ロードされていると想定していましたが、ポールプラグインに追加したときに1回しか実行されないのを見て、それを否定しました。

今はもう忘れてしまいましたが、--trace を使用しても1回しかロードされないことが示されると思います。間違っているかもしれませんが、記憶が正しければ、ロードが2回行われた場合、invoke および/または execute の行が2回表示されます。

docker_manager と poll、またはコアの何かとの間に、この動作の違いを説明できるような違いを見つけることができず、投稿したときにほぼ諦めていました。

「いいね!」 1

ちょっと遅れてしまったかもしれません :slight_smile:

新しいプラグインで同じ問題に遭遇しました。少し調べてみたところ、この問題は他のプラグイン(例:公式チャットプラグイン)でも発生しているようですが、タスクが複数回登録されるのを回避する動作する解決策を見つけました。

# 以前の登録をクリア
task('import_json:preview').clear

# タスク定義
desc 'Previews changes which would be applied by import_json'
task 'import_json:preview', [:file_path] => :environment do |_task, args|
  puts "Hello world!"
end

タスクの説明の 後に クリアすると、rake --tasks でタスクがリストされるのを防いでしまうため、それより 前に クリアする必要があります。

「いいね!」 3

これは、タスクを追加したときに同じ結果が得られるということですか、それともプラグインに既に存在するタスクがこの動作をするということですか?

情報ありがとうございます!クリアする必要があるのは少しハッキーに感じますが、確かに便利な回避策です。

他の人の便宜のために、あなたの投稿を解決策としてマークします。願わくば、より広範な原因が特定されることを願っています。質問は次のようになります。なぜ一部のプラグインではタスクが2回登録され、他のプラグインではそうならないのですか?

「これは、タスクを追加すると同じ結果が得られるということですか、それともプラグインに既に存在するタスクがこの動作をするということですか?」

私が開発したプラグイン内のタスクが2回実行される理由を理解しようとしている間に、Chatプラグイン内の既存のタスクをテストしたところ、それも2回実行されました。

他のプラグインのタスクもいくつかテストしましたが、どれだったかは覚えていません。いくつかは一度だけ実行されましたが、実装の違いについて明白なことは何もありませんでした。

オートロードと関係があるのでしょうか?

新しいプラグインでは、エンジンには次の行が含まれています。

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

lib をオートロードするのではなく、lib/tasks のオートロードを回避するために lib/some_path をオートロードしない場合、それは改善されるように見えますが、欠点はオートロードが壊れることです(ここで停止しました)。これは、補償するために多くの require_relative ステートメントを必要とする可能性があります…

「いいね!」 2

タスクをロードする仕組みが既に存在する場合、二重にロードされる原因となる可能性は確かに考えられます。

次のいずれかを使用することで、この問題に対処できるのではないかと思います(オートロードを一度行うことによる副作用が不明なため、後者の方が良いかもしれません)。

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.