Sid*_*Sid 6 ruby activerecord fork ruby-on-rails file-descriptor
我知道当我们分叉一个进程时,子进程会继承父进程打开文件描述符和偏移的副本.根据手册页,这指的是父母使用的相同文件描述符.基于该理论在以下程序中
puts "Process #{Process.pid}"
file = File.open('sample', 'w')
forked_pid = fork do
sleep(10)
puts "Writing to file now..."
file.puts("Hello World. #{Time.now}")
end
file.puts("Welcome to winter of my discontent #{Time.now}")
file.close
file = nil
问题1:
休眠10秒的分叉进程不应该丢失其文件描述符,并且在父进程完成并关闭文件并退出时无法写入文件.
问题2:但无论出于何种原因,如果这都有效,那么ActiveRecord在这种情况下如何失去连接.它只有在我设置:reconnect => trueActiveRecord连接时才能正常连接,这意味着它失去连接.
require "rubygems"
require "redis"
require 'active_record'
require 'mysql2'
connection = ActiveRecord::Base.establish_connection({
:adapter => 'mysql2',
:username => 'root_user',
:password => 'Pi',
:host => 'localhost',
:database => 'list_development',
:socket => '/var/lib/mysql/mysql.sock'
})
class User < ActiveRecord::Base
end
u = User.first
puts u.inspect
fork do
sleep 3
puts "*" * 50
puts User.first.inspect
puts "*" * 50
end
puts User.first.inspect
但是,同样不适用于Redis(v2.4.8),它不会再失去连接上的连接.它是否尝试在fork上进行内部重新连接?
如果是这样,那么为什么写文件程序不会抛出错误.
有人可以解释这里发生的事情吗?谢谢
如果您在一个进程中关闭文件描述符,它在另一进程中仍然有效,这就是您的文件示例工作正常的原因。
mysql 的情况有所不同,因为它是一个套接字,末尾有另一个进程。当您在 mysql 适配器上调用 close 时(或者当 ruby 退出时适配器被垃圾收集时),它实际上向服务器发送一个“QUIT”命令,表示您正在断开连接,因此服务器会断开其套接字一侧。一般来说,你真的不想在两个进程之间共享 mysql 连接 - 你会得到奇怪的错误,具体取决于两个进程是否试图同时使用套接字。
如果关闭 Redis 连接只是关闭套接字(而不是向服务器发送“我要离开”消息),则子连接应该继续工作,因为套接字实际上并未关闭
| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |