【问题标题】:invoking a script with fork using 'RAILS_ENV=#{Rails.env} bundle exec . . ' doesn't execute (Rails 2.1)使用 fork 调用脚本 'RAILS_ENV=#{​​Rails.env} bundle exec 。 . ' 不执行 (Rails 2.1)
【发布时间】:2015-03-20 17:27:34
【问题描述】:

相当深奥的问题,但为了我自己的启迪,我很好奇这怎么行不通。

我有一个脚本由在 Rails 2.1 上的旧系统上运行的 cron 触发

它获取要执行的任务列表。由于每个任务都可能长时间运行,因此它使用“fork”将任务置于后台。

我获取子进程的 pid。 使用“RAILS_ENV=Rails.env bundle exec child_script”调用进程不起作用。删除 RAILS_ENV 确实有效 (注意:直接从命令行运行子脚本就可以了。)

job_script_path = /path/to/child_script.rb
cmd = "RAILS_ENV=#{Rails.env} bundle exec #{job_script_path}
puts "Preparing to run #{cmd}"
ppid = fork{ system(cmd) }
puts "Fetched #{ppid} as parent process"

cpmd = "ps --ppid #{ppid}"
f = IO.popen(cpmd).readlines
puts "Output of #{cpmd}:"
puts "#{f}"

总是输出:

Preparing to run RAILS_ENV=development bundle exec /path/to/child_script.rb
Fetched 1234 as parent process
Output of ps --ppid 1234
PID TTY          TIME CMD

没有列出进程。

如果我放弃 RAILS_ENV=#{​​Rails.env} 它工作得很好。设置 rails 环境强制原子性怎么样?

更新:这更像是一个 Ruby 问题。我在跑 。 . . .红宝石 1.8.7

【问题讨论】:

  • 你有想过这个吗?我无法复制问题。
  • 我确实做到了。在下面发布答案

标签: ruby-on-rails ruby concurrency


【解决方案1】:

显然,您不能 fork 在 Rails 环境中运行的并发进程。但是,您可以派生一个不依赖于 Rails 环境的并发进程。

#Do not prepend RAILS_ENV to this, it doesn't allow concurrency (for some reason.)
cmd = "bundle exec #{job.script_path}"
logger.info "Preparing to run #{cmd}"
ppid = fork{ system(cmd) }
logger.info "Fetched #{ppid} as parent process"

剥离 Rails 环境可以工作。我没有找到确切的资源来解释为什么会这样。 Rails 环境在某种程度上是单一的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    相关资源
    最近更新 更多