On Mon, 5 Mar 2007, Andreas S. wrote:
Hi,
I am experiencing a very strange problem in my Rails app. I use popen3
to execute an external program. Everything works fine in Mongrel, but
when I use the app with LSAPI, after popen3 all MySQL queries fail with
“Mysql::Error (MySQL server has gone away)”. Once I comment out popen3
it works fine again.
Does anyone have the slightest idea about what goes wrong here?
guessing, but popen3 uses fork. forking with and open db handle is
undefined
for almost any db lib - of course people ignore this. i did, and had
all
sorts of issues. you can read about them here
Linux Clustering with Ruby Queue: Small Is Beautiful | Linux Journal
i bet what happens is that the parent (rails) has setup an at_exit
handler to
close the db on exit. when popen forks and does it’s thing in the
child, the
child’s death kills the db handle (at_exit handlers being inherited - of
course).
this shows what i’m talking about
harp:~ > cat a.rb
at_exit{ puts ‘close connection A’ }
fork{ }
Process.wait
class Object
alias_method ‘fork’, ‘fork’
def fork *a, &b
at_exit{ exit! }
fork *a, &b
end
end
module Kernel
alias_method ‘fork’, ‘fork’
def fork *a, &b
at_exit{ exit! }
fork *a, &b
end
end
at_exit{ puts ‘close connection B’ }
fork{ }
Process.wait
harp:~ > ruby a.rb
close connection A
i’d try putting this
class Object
alias_method ‘fork’, ‘fork’
def fork *a, &b
at_exit{ exit! }
fork *a, &b
end
end
module Kernel
alias_method ‘fork’, ‘fork’
def fork *a, &b
at_exit{ exit! }
fork *a, &b
end
end
in environment.rb or something. another idea, i’m grasping, is some
sort of
buffer flushing thing.
you could try
4242.times do |fd|
begin
IO.for_fd(fd).flush
rescue Errno::EBADF
end
end
right before the popen. wild ass guess though.
good luck.
-a