m6w6 / ext-pq

PostgreSQL client library (libpq) binding
BSD 2-Clause "Simplified" License
39 stars 7 forks source link

Bug POLLING_OK? #21

Closed ParkFramework closed 8 years ago

ParkFramework commented 8 years ago

Test for php-cli

<?php

use pq\Connection;

$db   = new Connection('user=postgres application_name=Test', Connection::ASYNC);

$dbIo = new EvIo($db->socket, Ev::READ, function() use($db)
{
    try
    {
        echo "Connect PostgreSQL server...\r\n";

        if($db->poll() === Connection::POLLING_OK)
        {
            echo "Restart PostgreSQL server...\r\n";

            exec('systemctl restart postgresql-9.6');

            if($db->poll() === Connection::POLLING_OK)
            {
                echo "IS BUG - POLLING_OK\r\n";

                try
                {
                    $db->execAsync('');
                }
                catch(Throwable $e)
                {
                    exit("Error: ".$e->getMessage()."\r\n");
                }
            }

            exit("IS OK\r\n");
        }
    }
    catch(Throwable $e)
    {
        echo "Error: ".$e->getMessage()."\r\n";
    }
});

$db->poll();
Ev::run();
DaveRandom commented 8 years ago

Can you explain what this snippet is trying to test? What scenario are you expecting this to happen in?

If anything this is a bug in libpq, as poll() is just passing through the return value of PQconnectPoll() at this point - but since you've already connected, I'd imagine that libpq is short-circuiting the return value because it knows it's already connected and doesn't have any work left to do.

You'd need to watch the socket for readability and detect the disconnect, you can't just poll the connection again.

If you'd like some reference on the programming flow, check out https://github.com/amphp/pgsql/tree/new-api/src - it's not thoroughly tested but it's known to work with everything I've thrown at it so far.

ParkFramework commented 8 years ago

Can you explain what this snippet is trying to test? What scenario are you expecting this to happen in?

PQconnectPoll() must return FAILED, it does it if has already been executed at least one sql query.

You'd need to watch the socket for readability and detect the disconnect, you can't just poll the connection again.

Where can I see an example?

m6w6 commented 8 years ago

Hey!

POLLING_OK just means nothing to write or read left, and as far as client/server communication is concerned everything has successfully been transmitted.

You cannot test for a broken connection except with a real action on the connection like an empty query.

HTH

m6w6 commented 8 years ago

Ah, FYI, here's the complete procedure about how to finish an asynchronous connect: https://mdref.m6w6.name/pq/Connection/:%20Asynchronous%20Usage#Complete.asynchronous.operation:

ParkFramework commented 8 years ago

You cannot test for a broken connection except with a real action on the connection like an empty query.

Okay :)