4

I recently upgraded from php 5.4.26 to 5.4.28 after the upgrade I am getting this error

Notice: Unknown: send of 6 bytes failed with errno=32 Broken pipe in Unknown on line 0

When ever I run the following code:

<?php
$tasks = array(
   '1'  => array(),
   '2'  => array(),
);

ini_set('display_errors', true);

class RedisClass {

    private $redis;

    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect('localhost', 6379);
    }

}

$redis = new RedisClass();

foreach ($tasks as $index => $task)
{
    $pid = pcntl_fork();

    // This is a child                                                                                                                                                          
    if($pid == 0)
    {
        echo "Running ".$index." child in ". getmypid() ."\n";
        break;
    }
}

switch($pid)
{
case -1 :
    die('could not fork');
    break;
case 0:
    // do the child code                                                                                                                                                        
    break;
default:
    while (pcntl_waitpid(0, $status) != -1)
    {
        $status = pcntl_wexitstatus($status);
        echo "Child completed with status $status\n";
    }
    echo "Child Done (says: ". getmypid() .")";
    exit;
}

If I only fork one child then I do not get the PHP Notice. If I run any more than 1 child I get the PHP Notice for every child except the first child.

Does anyone have any clues as to what is going on here?

I am assuming it is trying to close the Redis connection multiple times but this is code I have been running for at least 4 months with out any issues.

It only starting displaying these notices after the upgrade to 5.4.28.

I have looked at the PHP change logs but I cannot see anything that I think may explain this issue.

Should I report this to PHP as a bug?

UPDATE:

Looks like it "may" be a Redis issue, I am using phpredis I tested the same code with a mysql connection instead of loading Redis and I do not get the error.

class MysqlClass {
    private $mysqli;
    public function __construct()
    {
        $this->mysqli = mysqli_init();  //This is not the droid you are looking for                                                                                             
        $this->mysqli->real_connect('IP_ADDRESS',
                                    'USER_NAME',
                                    'PASSWORD');
    }
}

$mysql = new MysqlClass();
Alistair Prestidge
  • 673
  • 3
  • 9
  • 19
  • I have now posted an issue here as well to see if they can shed any light on the issue. https://github.com/nicolasff/phpredis/issues/474 – Alistair Prestidge May 17 '14 at 17:58
  • 1
    The example you are showing for MySQL should not work either as far as I know. When you create a mysql connection in the parent process all child processes will be able to use them. But, when the first child exists, it closes the mysql connection from the parent. Be very careful when forking in PHP. The child process will close most resources (file descriptors, db connections, sockets) when it exists. All other childs are not able to use those resources anymore afterwards – M. Dekker Oct 11 '15 at 13:48

1 Answers1

0

The problem here is that you do not reconnect Redis in the child process. Like Michael had said, you do not have an active connection from the second child onwards. That mysql example should not work if you also make some queries.

I have had the exact problematic behaviour with the "MySQL server has gone away" error and also with Redis.

The solution is to create a new connection to MySQL and to Redis in the child. Make sure if you have a singletone that handles the MySQL/Redis connection to reset the instances ( that was also a problem for me ).

Cosmin
  • 1,482
  • 12
  • 26
  • It looks like `phpredis` is smarter than `php-mysql` in that regard and does re-establish connection in forked processes automatically. It works for me in 99%. Still, occasionally under high load I see this issue. – Greendrake Jan 16 '17 at 05:51