From 746812e67bddf513c61b6bac35aa2f3b087d6aaa Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Mon, 19 Jul 2010 07:30:15 +0000 Subject: [PATCH] Apply fast-fail at connect time. If server is failing, the clients get error when connecting. --- include/objects.h | 1 + src/client.c | 2 +- src/objects.c | 57 +++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/include/objects.h b/include/objects.h index 3e2e6e9..25e1420 100644 --- a/include/objects.h +++ b/include/objects.h @@ -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); diff --git a/src/client.c b/src/client.c index cc6c416..e43ee12 100644 --- a/src/client.c +++ b/src/client.c @@ -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) diff --git a/src/objects.c b/src/objects.c index 07ad1cb..a391d5e 100644 --- a/src/objects.c +++ b/src/objects.c @@ -481,6 +481,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) { @@ -510,27 +543,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); -- 2.11.4.GIT