PhpOrient icon indicating copy to clipboard operation
PhpOrient copied to clipboard

Warning: socket_write(): unable to write to socket

Open lgoix opened this issue 9 years ago • 8 comments

Hello

I have a consumer that consume message from RabbitMQ. It means the php file is executed as long the supervisor don't stop it, or it die by itself.

The consumer select and insert into OrientDB. Sometime there is a problem with the socket connection with OrientDB and it will produce many exception:

Warning: socket_write(): unable to write to socket [32]: Broken pipe in /home/web1/myApplication/application/vendor/ostico/phporient/src/PhpOrient/Protocols/Binary/OrientSocket.php line 164"

The PhpOrient class is instanciated in Symfony2 with the service configurator.

I want to know if there is a way to reset the connection ? Is reseting the transport interface is a way to do it ?

$this->orientDBClient->setTransport(null);

Thanks

lgoix avatar Nov 30 '15 13:11 lgoix

Is your DB located on a remote server?

andreyvk avatar Nov 30 '15 14:11 andreyvk

@andreyvk : Yes

lgoix avatar Nov 30 '15 14:11 lgoix

Is your connection to the remote server unstable?

Have you tried catching a SocketException and re-establishing a connection again by instantiating a new PhpOrient client?

andreyvk avatar Nov 30 '15 14:11 andreyvk

What I mean is something like this. Of course this code below need more refining:

$client = getPhpOrientClient(); //suppose this is your custom function to instantiate  a connection

//try to do queries. if socket error happens more than 3 times, then quit
$errorCnt = 0;
do {
    try {
          //do your queries here
    }
    catch(SocketException $e) {
        $errorCnt++;
        $client = getPhpOrientClient();
    }
}
while($errorCnt < 3);

if($errorCnt >= 3) {
    //some serious issue happened
}

andreyvk avatar Nov 30 '15 14:11 andreyvk

I understand

The OrientDb client is injected in the application with all credentials, calling the dbOpen method, before I use it. It seems not possible in Symfony to reset the connexion.

I've looked into the project, I was thinking that if I put the transport = null, it will recreate the transport. (PhpOrient line 174)

I would think to create a decorator to PhpOrient client, and add a method to reconnect. Maybe it could be something valuable for the PhpOrient class ?

lgoix avatar Nov 30 '15 15:11 lgoix

I see, I completely overlooked that you were using Symphony. Sorry

I found that there's a connect() function in PhpOrient.php. on line 231. Maybe you can try calling that. You dont have to pass any parameters (it will re-use your last username and password it seems).

If that doesnt work then maybe @Ostico can help a little here.

andreyvk avatar Nov 30 '15 18:11 andreyvk

Hi @lgoix ,

there are some methods to reset/renew the connection for PhpOrient, surely the most simple one is to use it's internal transport layer to manually create a connection on the underlying OrientSocket:

use PhpOrient\PhpOrient;
use PhpOrient\Protocols\Binary\SocketTransport;

$config = [
        "hostname" => "localhost",
        "port"     => 2424,
        "connect"  => [
                "username" => "root",
                "password" => "root"
        ]
];

$client           = new PhpOrient();
$transport = new SocketTransport();
$this->assertInstanceOf( '\PhpOrient\Protocols\Common\AbstractTransport', $transport );
$this->assertInstanceOf( '\PhpOrient\Protocols\Common\TransportInterface', $transport );

$transport->configure( $config );
$client->setTransport( $transport );
$client->execute( 'connect' );

$this->assertNotEquals( -1, $client->getTransport()->getSessionId() );
$this->assertNotEquals( -1, $client->getTransport()->getProtocolVersion() );

So, you can inject a new socket inside your already configured client. You can also retain the preeceding socket object and re-enable the old connection by using:


$old_transport = $client->getTransport( );

$new_transport = new SocketTransport();
$transport->configure( $config );
$client->setTransport( $transport );

Ostico avatar Nov 30 '15 23:11 Ostico

Hi Ostico,

If you don't configure the $new_transport, it will use the config used at the first time ?

lgoix avatar Dec 02 '15 14:12 lgoix