插件 rake 任务多次运行 - 我们遗漏了什么?

我正在向 docker_manager 插件添加一个 rake 任务,但我发现调用该任务时它会运行两次。在其最简单的形式中,我可以将 testing.rake 添加到 lib/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 中出现这种情况的原因提供建议。

3 个赞

你解决这个问题了吗?

我遇到了类似的问题:

如果我在插件中创建一个 rake 任务,例如:lib/tasks/test.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 个赞

好的,我设法将任务的运行次数减少到两次,方法是_从 initialize 块中移除_该任务的加载。 Apparently,只需将其放在 /lib/tasks 中而无需加载即可。

这使我的运行次数减少到 1 次(总共 2 次!)::sweat_smile:

此论坛的帖子数为 366
此论坛的帖子数为 366

这只是重复了 OP 的经历。

2 个赞

可惜没有。起初我以为是核心中的某些东西导致它被加载了两次,但看到它在添加到 poll 插件时只运行了一次,似乎反驳了这一点。

我现在有点忘了,但我想使用 --trace 也许也能显示它只加载了一次。我可能是错的,但如果我没记错的话,如果它被加载了两次,invoke 和/或 execute 行会显示两次。

我未能找到 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 个赞

这是否意味着您在向其添加任务时会得到相同的结果,还是插件中已有的任务具有此行为?

感谢您的信息!不得不清除它感觉有点笨拙,但这无疑是一个有用的解决方法。

为了方便他人,我将把您的帖子标记为解决方案。希望根本原因仍能被查明,我想问题变成了:为什么有些插件中的任务会注册两次,而其他插件则不会?

这是指将任务添加到其中会得到相同的结果,还是指插件中已有的任务具有此行为?

在尝试理解我自己的插件中开发的任务为何被执行两次时,我测试了 Chat 插件中的一个现有任务,它也被执行了两次。

我也测试了其他插件的一些任务,但记不清是哪些了。有些执行了一次,但实现方式上没有明显区别。

也许这与自动加载有关?

在一个新的插件中,引擎包含这一行:

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

如果我不自动加载 lib 而是自动加载 lib/some_path 以避免自动加载 lib/tasks,情况似乎有所改善,但缺点是它会破坏自动加载(我在这里停了下来)。这可能会导致需要添加大量 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.