如何在 ruby​​ 中控制(启动/终止)后台进程(服务器应用程序)

发布于 2024-08-16 06:13:00 字数 345 浏览 5 评论 0原文

我正在尝试通过 ruby​​ 设置一个用于集成测试(实际上是规格)的服务器,但不知道如何控制该过程。

所以,我想做的是:

  1. 为我的 gem 运行一个 rake 任务来执行集成规范,
  2. 该任务需要首先启动服务器(我使用 webrick),然后
  3. 在执行规范后运行规范,它应该杀死 webrick所以我没有留下一些未使用的后台进程

webrick 不是必需的,但它包含在 ruby​​ 标准库中,因此能够使用它会很棒。

希望任何人都能够提供帮助!

附注我在 Linux 上运行,所以在 Windows 上进行这项工作并不是我的首要任务(现在)。

i'm trying to set up a server for integration tests (specs actually) via ruby and can't figure out how to control the process.

so, what i'm trying to do is:

  1. run a rake task for my gem that executes the integration specs
  2. the task needs to first start a server (i use webrick) and then run the specs
  3. after executing the specs it should kill the webrick so i'm not left with some unused background process

webrick is not a requirement, but it's included in the ruby standard library so being able to use it would be great.

hope anyone is able to help!

ps. i'm running on linux, so having this work for windows is not my main priority (right now).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

背叛残局 2024-08-23 06:13:00

标准方法是使用系统函数fork(复制当前进程)、exec(用可执行文件替换当前进程)和kill(向进程发送信号以终止它)。

例如:

pid = fork do
  # this code is run in the child process
  # you can do anything here, like changing current directory or reopening STDOUT
  exec "/path/to/executable"
end

# this code is run in the parent process
# do your stuffs

# kill it (other signals than TERM may be used, depending on the program you want
# to kill. The signal KILL will always work but the process won't be allowed
# to cleanup anything)
Process.kill "TERM", pid

# you have to wait for its termination, otherwise it will become a zombie process
# (or you can use Process.detach)
Process.wait pid

这应该适用于任何类 Unix 系统。 Windows 以不同的方式创建进程。

The standard way is to use the system functions fork (to duplicate the current process), exec (to replace the current process by an executable file), and kill (to send a signal to a process to terminate it).

For example :

pid = fork do
  # this code is run in the child process
  # you can do anything here, like changing current directory or reopening STDOUT
  exec "/path/to/executable"
end

# this code is run in the parent process
# do your stuffs

# kill it (other signals than TERM may be used, depending on the program you want
# to kill. The signal KILL will always work but the process won't be allowed
# to cleanup anything)
Process.kill "TERM", pid

# you have to wait for its termination, otherwise it will become a zombie process
# (or you can use Process.detach)
Process.wait pid

This should work on any Unix like system. Windows creates process in a different way.

执妄 2024-08-23 06:13:00

我只需要做类似的事情,这就是我想到的。 @Michael Witrant 的回答让我开始了,但我改变了一些东西,比如使用 Process.spawn 而不是 fork (更新更好) 。

# start spawns a process and returns the pid of the process
def start(exe)
    puts "Starting #{exe}"
    pid = spawn(exe)
    # need to detach to avoid daemon processes: http://www.ruby-doc.org/core-2.1.3/Process.html#method-c-detach
    Process.detach(pid)
    return pid
end

# This will kill off all the programs we started
def killall(pids)
  pids.each do |pid|
      puts "Killing #{pid}"
      # kill it (other signals than TERM may be used, depending on the program you want
      # to kill. The signal KILL will always work but the process won't be allowed
      # to cleanup anything)
      begin
        Process.kill "TERM", pid

        # you have to wait for its termination, otherwise it will become a zombie process
        # (or you can use Process.detach)
        Process.wait pid
      rescue => ex
        puts "ERROR: Couldn't kill #{pid}. #{ex.class}=#{ex.message}"
      end
  end
end

# Now we can start processes and keep the pids for killing them later
pids = []
pids << start('./someprogram')

# Do whatever you want here, run your tests, etc. 

# When you're done, be sure to kill of the processes you spawned
killall(pids)

这就是她写的全部内容,尝试一下并让我知道它是如何工作的。

I just had to do something similar and this is what I came up with. @Michael Witrant's answer got me started, but I changed some things like using Process.spawn instead of fork (newer and better).

# start spawns a process and returns the pid of the process
def start(exe)
    puts "Starting #{exe}"
    pid = spawn(exe)
    # need to detach to avoid daemon processes: http://www.ruby-doc.org/core-2.1.3/Process.html#method-c-detach
    Process.detach(pid)
    return pid
end

# This will kill off all the programs we started
def killall(pids)
  pids.each do |pid|
      puts "Killing #{pid}"
      # kill it (other signals than TERM may be used, depending on the program you want
      # to kill. The signal KILL will always work but the process won't be allowed
      # to cleanup anything)
      begin
        Process.kill "TERM", pid

        # you have to wait for its termination, otherwise it will become a zombie process
        # (or you can use Process.detach)
        Process.wait pid
      rescue => ex
        puts "ERROR: Couldn't kill #{pid}. #{ex.class}=#{ex.message}"
      end
  end
end

# Now we can start processes and keep the pids for killing them later
pids = []
pids << start('./someprogram')

# Do whatever you want here, run your tests, etc. 

# When you're done, be sure to kill of the processes you spawned
killall(pids)

That's about all she wrote, give it a try and let me know how it works.

羅雙樹 2024-08-23 06:13:00

我尝试过 fork,但是当 ActiveRecord 参与这两个进程时,它会出现一些问题。我建议使用 Spawn 插件 (http://github.com/tra/spawn)。它只进行 fork,但会处理 ActiveRecord。

I have tried fork, but it has kind of problems when ActiveRecord is involved in both the processes. I would suggest Spawn plugin (http://github.com/tra/spawn). It does fork only but takes care of ActiveRecord.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文