I want to fork a child process and use instantiated objects from the
parent
process. Is this possible?
obj = Object.new
fork do
doSomething(obj)
end
I want to fork a child process and use instantiated objects from the
parent
process. Is this possible?
obj = Object.new
fork do
doSomething(obj)
end
Joey M. wrote:
I want to fork a child process and use instantiated objects from the parent
process. Is this possible?obj = Object.new
fork do
doSomething(obj)
end
Yes, but it is a copy of the original, so modifications in the child
don’t affect the parent.
Joey M. wrote:
I want to fork a child process and use instantiated objects from the
parent
process. Is this possible?obj = Object.new
fork do
doSomething(obj)
end
class Dog
def greet
puts ‘hello’
end
end
d = Dog.new
fork do
d.greet
end
Process.wait
–output:–
hello
I see,
I have a class to handle interfacing to the database. The initialization
of
the class will connect to the db and another method will close the
connection and there are query functions for handling the queries and
results. This object is then passed into new objects on their
initialization. The problem comes in when I iterate through a set of
objects
creating a fork for each one. After the first object I am getting a
“database went away error”. My code looks like the following:
db = MySQL.new
fork do
obj1 = Object1.new(db)
obj1.addToDb
end
Process.wait
fork do
obj2 = Object2.new(db) #Object1 and Object2 are inherited from the
same
superclass
ob2.addToDb #db error occurs here
end
Process.wait
db.closeDB
–output–
obj1 info added to db!
Error message: MySQL server has gone away
I know I am missing a key concept here. This is the first time I have
worked
with forked processes.
On Wed, Mar 26, 2008 at 7:39 PM, Joel VanderWerf
[email protected]
Is tonight UNIX night?
On Wed, Mar 26, 2008 at 6:09 PM, Joey M. [email protected]
wrote:
superclass
ob2.addToDb #db error occurs here
end
Process.wait
When you fork you create a new process. When you reach the “end” of
the block, that process exits. My guess is that when your code passes
the first Process.wait, your MySQL object was torn down by the dieing
process.
Look at this code:
#!/usr/bin/env ruby
END { puts “Bye from #{Process.pid}” }
fork do
puts “Hello from #{Process.pid}”
end
Process.wait
fork do
puts “Hello from #{Process.pid}”
end
Process.wait
What do you expect to see when you run it?
Marcelo
Joey M. wrote:
fork do
obj1 = Object1.new(db)
obj1.addToDb
At this point in the child, the process is about to exit, the db object
in the child is freed, and (my guess) a finalizer is executed which
closes the database connection.
end
Process.waitfork do
obj2 = Object2.new(db) #Object1 and Object2 are inherited from the same
superclass
ob2.addToDb #db error occurs here
…which is the same as the connection you’re trying to use here (same
connection because of the fork), through this copy of the db object.
But that’s only my guess. I don’t know how the MySQL ruby interface
works, or if there is a way to tell it not to close the connection when
the child exits.
Possibly informative:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/117013
If you really need the forks to access the database, they could start
new connections. If there’s a performance problem with that, you could
keep a pool of child processes and send them commands from the parent.
(The slave gem might be a good way to do that.)
2008/3/27, Joey M. [email protected]:
I have a class to handle interfacing to the database. The initialization of
the class will connect to the db and another method will close the
connection and there are query functions for handling the queries and
results. This object is then passed into new objects on their
initialization.
This cannot possibly work, as you have discovered. You need to open
DB connections in child processes individually because there are
usually socket connections involved and you cannot share the same
connection between processes because the DB needs to keep them
separate even though you can share the client socket.
The problem comes in when I iterate through a set of objects
creating a fork for each one. After the first object I am getting a
“database went away error”. My code looks like the following:
I know I am missing a key concept here. This is the first time I have worked
with forked processes.
See above.
Kind regards
robert
Joel VanderWerf wrote:
Joey M. wrote:
I want to fork a child process and use instantiated objects from the parent
process. Is this possible?obj = Object.new
fork do
doSomething(obj)
endYes, but it is a copy of the original, so modifications in the child
don’t affect the parent.
Who said anyting about modifying the original? The post reads:
I want to fork a child process and use instantiated objects from the
parent
On Wed, 26 Mar 2008 19:09:10 -0500, Joey M. wrote:
I want to fork a child process and use instantiated objects from the
parent
process. Is this possible?
Yes, but it is a copy of the original, so modifications in the child
don’t affect the parent.
[Note: parts of this message were removed to make it a legal post.]
I see,
I have a class to handle interfacing to the database. The initialization
of the class will connect to the db and another method will close the
connection and there are query functions for handling the queries and
results. This object is then passed into new objects on their
initialization. The problem comes in when I iterate through a set of
objects creating a fork for each one. After the first object I am
getting a “database went away error”. My code looks like the following:
When you fork() a new process, both the memory is copied, but both the
parent and child processes share the same open files, including the same
socket (because there’s no real concept of duplicating the socket at
both
ends). When one process quits, it closes the connection automatically
(this is done by a finalizer on the database handle, or something like
that, possibly buried in the C library). In the MySQL protocol[1], this
sends a command over the socket to the MySQL server, and the server and
client close their connection. The second process, which still has the
socket open, now discovers that the connection is closed and reports
that
the server has gone away.
A good solution to this problem is to fork a DRb server that serves up
the database access stuff, and allocate the Mysql connection only inside
that process. DRb connections will work just fine across forks.
(I know I implemented this before, but I can’t find the sample code.)
–Ken
[1] http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol
On Wed, 26 Mar 2008 19:09:10 -0500, Joey M. wrote:
[Note: parts of this message were removed to make it a legal post.]
I see,
I have a class to handle interfacing to the database. The initialization
of the class will connect to the db and another method will close the
connection and there are query functions for handling the queries and
results. This object is then passed into new objects on their
initialization. The problem comes in when I iterate through a set of
objects creating a fork for each one. After the first object I am
getting a “database went away error”.
Here we go. Here’s my sample code for solving this issue.
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/204151
–Ken
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs