[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Joey Marino

3/26/2008 10:37:00 PM

[Note: parts of this message were removed to make it a legal post.]

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 Marino

9 Answers

7stud --

3/26/2008 11:03:00 PM

0

Joey Marino 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
--
Posted via http://www.ruby-....

Joel VanderWerf

3/26/2008 11:39:00 PM

0

Joey Marino 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.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Joey Marino

3/27/2008 12:09:00 AM

0

[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:

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 <vjoel@path.berkeley.edu>
wrote:

> Joey Marino 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.
>
> --
> vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
>
>


--
Joey Marino

Joel VanderWerf

3/27/2008 3:14:00 AM

0

Joey Marino wrote:
> 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

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.wait
>
> fork 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-t...

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.)

> end
> Process.wait
>
> db.closeDB



--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Marcelo

3/27/2008 3:17:00 AM

0

Is tonight UNIX night? :-)

On Wed, Mar 26, 2008 at 6:09 PM, Joey Marino <joey.da3rd@gmail.com> wrote:

> 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

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

7stud --

3/27/2008 3:46:00 AM

0

Joel VanderWerf wrote:
> Joey Marino 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.

Who said anyting about modifying the original? The post reads:

>I want to fork a child process and *use* instantiated objects from the
>parent
--
Posted via http://www.ruby-....

Robert Klemme

3/27/2008 12:40:00 PM

0

2008/3/27, Joey Marino <joey.da3rd@gmail.com>:
> 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

--
use.inject do |as, often| as.you_can - without end

Ken Bloom

3/27/2008 11:23:00 PM

0

On Wed, 26 Mar 2008 19:09:10 -0500, Joey Marino 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_ClientServe...

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Ken Bloom

3/27/2008 11:35:00 PM

0

On Wed, 26 Mar 2008 19:09:10 -0500, Joey Marino 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-t...

--Ken

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...