如何解决Rails:系统进程不会在Rails服务器中启动,但会在Rails控制台中
我想在服务器启动时启动 ngrok 进程。为此,我对ngrok.rb库进行了编码,并在初始化程序中对其进行了调用
app / lib / ngrok.rb
require "singleton"
class Ngrok
include Singleton
attr_accessor :api_url,:front_url
def start
if is_running?
return fetch_urls
end
authenticate
started = system("ngrok start --all -log=stdout > #{ENV['APP_ROOT']}/log/ngrok.log &")
system("sleep 1")
if !started
return { api: nil,front: nil }
end
urls = fetch_urls
sync_urls(urls["api_url"],urls["front_url"])
return urls
end
def sync_urls(api_url,front_url)
NgrokSyncJob.perform_later(api_url,front_url)
end
def is_running?
return system("ps aux | grep ngrok")
end
def restart
stop
return start
end
def stop
return system("pkill ngrok")
end
def authenticate
has_file = system("ls ~/.ngrok2/ngrok.yml")
if has_file
return true
else
file_created = system("ngrok authtoken #{ENV['NGROK_TOKEN']}")
if file_created
return system("cat " + ENV['APP_ROOT'] + '/essentials/ngrok/example.yml >> ~/.ngrok2/ngrok.yml')
else
return false
end
end
end
def fetch_urls
logfile = ENV['APP_ROOT'] + '/log/ngrok.log'
file = File.open logfile
text = file.read
api_url = nil
front_url = nil
text.split("\n").each do |line|
next if !line.include?("url=") || !line.include?("https")
if line.split("name=")[1].split(" addr=")[0] == "ncommerce-api"
api_url = line.split("url=")[1]
elsif line.split("name=")[1].split(" addr=")[0] == "ncommerce"
front_url = line.split("url=")[1]
end
end
file.close
self.api_url = api_url
self.front_url = front_url
res = {}
res["api_url"] = api_url
res["front_url"] = front_url
return res
end
end
config / initializers / app-init.rb
module AppModule
class Application < Rails::Application
config.after_initialize do
puts "XXXXXXXXXXXXXXXXXXXXXXX"
Ngrok.instance.start
puts "XXXXXXXXXXXXXXXXXXXXXXX"
end
end
end
当我输入铁路服务时,这是输出示例
因此我们可以确定我的初始化程序正在被调用,但是当我查看Rails控制台是否正在运行时,不是!
但是当我在Rails控制台中输入Ngrok.instance.start
时,输出如下:
它开始了!
所以,我的问题是:为什么system("ngrok start --all -log=stdout > #{ENV['APP_ROOT']}/log/ngrok.log &")
不在地球上,但在轨道控制台上工作?
更新
如果我在ngrok.rb中使用'byebug'并使用rails服务,当我以“ continue”退出byebug时,将创建并运行ngrok进程
解决方法
您正在使用system()
在后台启动ngrok进程的方式来创建孤立进程:
system("ngrok start --all -log=stdout > #{ENV['APP_ROOT']}/log/ngrok.log &")
请注意在命令行末尾的&
。
我需要有关您的运行时环境的更多详细信息,以准确地告诉您哪个系统策略在启动后立即杀死孤立的ngrok进程(哪个操作系统?如果是Linux,它是否基于systemd?怎么办?您是从终端还是作为系统服务启动Rails服务器?)。
但这是怎么回事:
-
system()
启动/bin/sh
的实例来解释命令行 -
/bin/sh
在后台启动ngrok进程并终止 - ngrok现在是“孤立的”,这意味着其父进程
/bin/sh
已终止,因此不能wait(2)
将ngrok进程用于 - 取决于环境,终止的
/bin/sh
可能会通过SIGHUP信号杀死ngrok。 - 或操作系统通常将ngrok重定向到init进程(但这要视情况而定)
在两种情况下,当您使用Rails控制台或Byebug时,您都将进入交互式环境,该环境将以适合交互式执行的方式准备“进程组”,“会话ID”和“控制终端”。这些属性由子进程(如ngrok)继承。这会影响有关孤立后台进程处理的系统策略。
从Rails Server启动ngrok时,这些属性将有所不同(取决于Rails Server的启动方式)。
这是一篇不错的文章,介绍了可能涉及的某些操作系统机制:https://www.jstorimer.com/blogs/workingwithcode/7766093-daemon-processes-in-ruby
通过使用Ruby的Process.spawn
来启动后台进程,并结合您的案例中的Process.detach
,您可能会获得更好的成功。这样可以避免孤立ngrok过程。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。