Re: Forking and database connections

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey Dwight,

After getting your first e-mail, I started adding the PEAR::DB persistent
connection code.  Unfortunately, it yielded the same results that I was
getting before.

At a hunch, I created a second proof-of-concept script that uses the mysql_*
functions in the PHP base.  For each of these, I set the $new_link parameter
in the mysql_connect() function to "true".  As it turns out, the primary $db
link that was originally created in the parent process *is* destroyed when
the first child process closes -- this makes sense, however.  If I re-create
that thread after spawning all the child processes, though, it works
beautifully!

So it looks like this is a bug with PEAR::DB in handling persistent
connections across forked processes.  I'll go ahead and file it with the
PEAR::DB folk and include the two scripts in the bug request.

Again, thanks for your help!  It was really beneficial to have a second set
of eyes and a sounding board for getting through this problem.

In case anyone wants the second proof-of-concept script:

<?php

# Database table definition
# -------------------------
# CREATE TABLE `logs` (
#      `message` VARCHAR(128) NOT NULL
# );

/* Create the initial database connection for the parent process */
$db = mysql_connect('localhost', 'test', 'test', true);
mysql_select_db('testdb', $db);

/* Perform a DB update */
mysql_query("INSERT INTO `logs` (`message`) VALUES ('Started parent
process')", $db);

/* Create the child processes */
$childPids = array();
for ( $i = 0; $i < 5; $i++ ) {
        $pid = pcntl_fork();
        if ( $pid == -1 ) {
                die("\nUnable to fork!\n");
        } else if ( $pid ) {
                /* Parent process */
                echo "Child process $pid created\n";
                array_push($childPids, $pid);
        } else {
                /* Child process */
                $myPid = posix_getpid();

                /* Create a new database connection for the child process */
                $db2 = mysql_connect('localhost', 'test', 'test', true);
                mysql_select_db('testdb', $db2);

                mysql_query("INSERT INTO `logs` (`message`) VALUES ('Child
process $myPid started')", $db2);

                /* Add some latency for testing purposes */
                sleep(5);

                mysql_query("INSERT INTO `logs` (`message`) VALUES ('Child
process $myPid ended')", $db2);

                exit;
        }
}

$db3 = mysql_connect('localhost', 'test', 'test', true);
mysql_select_db('testdb', $db3);

/* Wait for the children to finish */
foreach ( $childPids as $pid ) {
        $msg = "Parent process waiting on child process $pid";
        echo $msg . "\n";
        mysql_query("INSERT INTO `logs` (`message`) VALUES ('$msg')", $db3);

        pcntl_waitpid($pid, $status);

        $msg = "Parent process detected child process $pid is finished";
        echo $msg . "\n";
        mysql_query("INSERT INTO `logs` (`message`) VALUES ('$msg')", $db3);
}

mysql_query("INSERT INTO `logs` (`message`) VALUES ('Parent process is
finished')", $db3);

?>

Thanks!
Chris





On 4/23/07 10:43 AM, "Dwight Altman" <dwight@xxxxxxxxxxxx> wrote:

> To use a PEAR::DB persistent connection, try
> $db = DB::connect($dsn, TRUE);
> or
> $db = DB::connect($dsn, true);
> 
> Googled for "pear::db persistent connection" and got
> http://vulcanonet.com/soft/?pack=pear_tut
> 
> 
> Regards,
> Dwight
> 
>> -----Original Message-----
>> From: Dwight Altman [mailto:dwight@xxxxxxxxxxxx]
>> 
>> Where in your code does it say you are using persistent connections?

-- 
PHP Database Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [PHP Users]     [Postgresql Discussion]     [Kernel Newbies]     [Postgresql]     [Yosemite News]

  Powered by Linux