]> granicus.if.org Git - pgbouncer/commitdiff
Apply fast-fail at connect time.
authorMarko Kreen <markokr@gmail.com>
Mon, 19 Jul 2010 07:30:15 +0000 (07:30 +0000)
committerMarko Kreen <markokr@gmail.com>
Wed, 4 Aug 2010 04:06:16 +0000 (07:06 +0300)
If server is failing, the clients get error when connecting.

include/objects.h
src/client.c
src/objects.c

index ac03c6f72320c961a0ad14af7d9582975a6c2920..616e6fe00ac0a05ffaf876ec421effe82d7312eb 100644 (file)
@@ -35,6 +35,7 @@ PgPool *get_pool(PgDatabase *, PgUser *);
 bool find_server(PgSocket *client)             _MUSTCHECK;
 bool release_server(PgSocket *server)          /* _MUSTCHECK */;
 bool finish_client_login(PgSocket *client)     _MUSTCHECK;
+bool check_fast_fail(PgSocket *client)         _MUSTCHECK;
 
 PgSocket * accept_client(int sock, const struct sockaddr_in *addr, bool is_unix) _MUSTCHECK;
 void disconnect_server(PgSocket *server, bool notify, const char *reason, ...) _PRINTF(3, 4);
index a5acf22cef53dc0af0811d512d2f25ee2c7672a8..c23b561d5c59c1e0acc1dfcbf0f063d8b1e2c850 100644 (file)
@@ -97,7 +97,7 @@ bool set_pool(PgSocket *client, const char *dbname, const char *username)
                return false;
        }
 
-       return true;
+       return check_fast_fail(client);
 }
 
 static bool decide_startup_pool(PgSocket *client, PktHdr *pkt)
index 3a98a4310606cc7f56fea7757ded092a8953c18c..743ca57fa5b9938cd12bd6cee66cb92b360b986c 100644 (file)
@@ -484,6 +484,39 @@ void activate_client(PgSocket *client)
        sbuf_continue(&client->sbuf);
 }
 
+/*
+ * Don't let clients queue at all, if there is no working server connection.
+ *
+ * It must still allow following cases:
+ * - empty pool on startup
+ * - idle pool where all servers are removed
+ *
+ * Current assumptions:
+ * - old server connections will be dropped by query_timeout
+ * - new server connections fail due to server_connect_timeout, or other failure
+ *
+ * So here we drop client if all server connections have been dropped
+ * and new one's fail.
+ */
+bool check_fast_fail(PgSocket *client)
+{
+       int cnt;
+       PgPool *pool = client->pool;
+
+       /* reject if no servers and last connect failed */
+       if (!pool->last_connect_failed)
+               return true;
+       cnt = pool_server_count(pool) - statlist_count(&pool->new_server_list);
+       if (cnt)
+               return true;
+       disconnect_client(client, true, "no working server connection");
+
+       /* usual relaunch wont work, as there are no waiting clients */
+       launch_new_connection(pool);
+
+       return false;
+}
+
 /* link if found, otherwise put into wait queue */
 bool find_server(PgSocket *client)
 {
@@ -513,27 +546,9 @@ bool find_server(PgSocket *client)
                                break;
                }
 
-               /*
-                * Don't let clients queue at all, if there is no working server connection.
-                *
-                * It must still allow following cases:
-                * - empty pool on startup
-                * - idle pool where all servers are removed
-                *
-                * Current logic:
-                * - old server connections will be dropped by query_timeout
-                * - new server connections fail due to server_connect_timeout, or other failure
-                */
-               if (!server && pool->last_connect_failed) {
-                       int cnt = pool_server_count(pool) - statlist_count(&pool->new_server_list);
-                       if (!cnt) {
-                               /* usual relaunch wont work, as there are no waiting clients */
-                               launch_new_connection(client->pool);
-
-                               disconnect_client(client, true, "no working server connection");
-                               return false;
-                       }
-               }
+               if (!server && !check_fast_fail(client))
+                       return false;
+
        }
        Assert(!server || server->state == SV_IDLE);