pgqd: Make connection handling more robust
authorMarko Kreen <markokr@gmail.com>
Mon, 24 Sep 2012 09:41:47 +0000 (12:41 +0300)
committerMarko Kreen <markokr@gmail.com>
Mon, 24 Sep 2012 13:46:52 +0000 (16:46 +0300)
There are reports of fatals() and stalls
when server goes down.  Plug potential holes.

* check for DB_CLOSED in tick_handler
* check for TUPLES_OK everywhere

sql/ticker/maint.c
sql/ticker/retry.c
sql/ticker/ticker.c

index 159380dc7d40c3092b20a464030f0435729c0504..bc6ae5fa1047f8443b76271b10a6f4bc19ac2043 100644 (file)
@@ -253,6 +253,10 @@ static void maint_handler(struct PgSocket *s, void *arg, enum PgEvent ev, PGresu
                        run_test_version(db);
                break;
        case PGS_RESULT_OK:
+               if (PQresultStatus(res) != PGRES_TUPLES_OK) {
+                       close_maint(db, 20);
+                       return;
+               }
                switch (db->maint_state) {
                case DB_MAINT_TEST_VERSION:
                        if (has_ops(res)) {
index b70b7747c366f2f3c5b8f272364d67020a278f57..3df31747d1f6daaa771dca2f201880c77a14a28d 100644 (file)
@@ -38,7 +38,10 @@ static void retry_handler(struct PgSocket *s, void *arg, enum PgEvent ev, PGresu
                run_retry(db);
                break;
        case PGS_RESULT_OK:
-               parse_retry(db, res);
+               if (PQresultStatus(res) != PGRES_TUPLES_OK)
+                       close_retry(db, 20);
+               else
+                       parse_retry(db, res);
                break;
        case PGS_TIMEOUT:
                log_debug("%s: retry timeout", db->name);
index cf2515902ce1e63472e953f1c24297cfe5660455..e2629c1fee57d5cdc718069f5bf5220a5019d0ac 100644 (file)
@@ -84,12 +84,17 @@ static void parse_ticker_result(struct PgDatabase *db, PGresult *res)
 static void tick_handler(struct PgSocket *s, void *arg, enum PgEvent ev, PGresult *res)
 {
        struct PgDatabase *db = arg;
+       ExecStatusType st;
 
        switch (ev) {
        case PGS_CONNECT_OK:
                run_pgq_check(db);
                break;
        case PGS_RESULT_OK:
+               if (PQresultStatus(res) != PGRES_TUPLES_OK) {
+                       close_ticker(db, 10);
+                       break;
+               }
                switch (db->state) {
                case DB_TICKER_CHECK_PGQ:
                        parse_pgq_check(db, res);
@@ -100,8 +105,15 @@ static void tick_handler(struct PgSocket *s, void *arg, enum PgEvent ev, PGresul
                case DB_TICKER_RUN:
                        parse_ticker_result(db, res);
                        break;
+               case DB_CLOSED:
+                       st = PQresultStatus(res);
+                       log_warning("%s: Weird state: RESULT_OK + DB_CLOSED (%s)",
+                                   db->name, PQresStatus(st));
+                       close_ticker(db, 10);
+                       break;
                default:
-                       fatal("bad state");
+                       log_warning("%s: bad state: %d", db->name, db->state);
+                       close_ticker(db, 10);
                }
                break;
        case PGS_TIMEOUT: