Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warning: socket_write(): unable to write to socket #57

Open
lgoix opened this issue Nov 30, 2015 · 8 comments
Open

Warning: socket_write(): unable to write to socket #57

lgoix opened this issue Nov 30, 2015 · 8 comments
Labels

Comments

@lgoix
Copy link

lgoix commented Nov 30, 2015

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

@andreyvk
Copy link

Is your DB located on a remote server?

@lgoix
Copy link
Author

lgoix commented Nov 30, 2015

@andreyvk : Yes

@andreyvk
Copy link

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
Copy link

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
}

@lgoix
Copy link
Author

lgoix commented Nov 30, 2015

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 ?

@andreyvk
Copy link

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.

@Ostico
Copy link
Owner

Ostico commented Nov 30, 2015

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 Ostico added the FAQ label Dec 1, 2015
@lgoix
Copy link
Author

lgoix commented Dec 2, 2015

Hi Ostico,

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants