From: Marko Kreen Date: Wed, 1 Aug 2007 22:00:47 +0000 (+0000) Subject: cancel of pause/resume, dont drop idle clients X-Git-Tag: pgbouncer_1_1~67 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8613ca9320d1deacf30ad5b24d93a712c2ef41ee;p=pgbouncer cancel of pause/resume, dont drop idle clients --- diff --git a/doc/todo.txt b/doc/todo.txt index da65c86..c38e1ee 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -2,7 +2,6 @@ == Small stuff == - * cancel of SUSPEND/PAUSE * suspend_timeout - drop stalled conns == Low-prio == diff --git a/src/admin.c b/src/admin.c index 2e39beb..4c51129 100644 --- a/src/admin.c +++ b/src/admin.c @@ -622,6 +622,14 @@ static bool admin_cmd_shutdown(PgSocket *admin, const char *arg) return true; } +static void full_resume(void) +{ + int tmp_mode = cf_pause_mode; + cf_pause_mode = P_NONE; + if (tmp_mode == P_SUSPEND) + resume_all(); +} + /* Command: RESUME */ static bool admin_cmd_resume(PgSocket *admin, const char *arg) { @@ -629,17 +637,11 @@ static bool admin_cmd_resume(PgSocket *admin, const char *arg) return admin_error(admin, "admin access needed"); if (!arg[0]) { - int tmp_mode = cf_pause_mode; log_info("RESUME command issued"); - cf_pause_mode = P_NONE; - switch (tmp_mode) { - case P_SUSPEND: - resume_all(); - case P_PAUSE: - break; - default: + if (cf_pause_mode != P_NONE) + full_resume(); + else return admin_error(admin, "Pooler is not paused/suspended"); - } } else { PgDatabase *db = find_database(arg); log_info("PAUSE '%s' command issued", arg); @@ -1012,3 +1014,21 @@ void admin_pause_done(void) } } +/* admin on console has pressed ^C */ +void admin_handle_cancel(PgSocket *admin) +{ + bool res; + + /* weird, but no reason to fail */ + if (!admin->wait_for_response) + slog_warning(admin, "admin cancel request for non-waiting client?"); + + if (cf_pause_mode != P_NONE) + full_resume(); + + /* notify readiness */ + SEND_ReadyForQuery(res, admin); + if (!res) + disconnect_client(admin, false, "readiness send failed"); +} + diff --git a/src/admin.h b/src/admin.h index dcfd14c..6163fa9 100644 --- a/src/admin.h +++ b/src/admin.h @@ -22,3 +22,5 @@ bool admin_error(PgSocket *console, const char *fmt, ...); void admin_pause_done(void); void admin_flush(PgSocket *admin, PktBuf *buf, const char *desc); bool admin_ready(PgSocket *admin, const char *desc); +void admin_handle_cancel(PgSocket *client); + diff --git a/src/objects.c b/src/objects.c index ebb9b28..4e3387a 100644 --- a/src/objects.c +++ b/src/objects.c @@ -862,8 +862,20 @@ void accept_cancel_request(PgSocket *req) /* not linked client, just drop it then */ if (!main_client->link) { - disconnect_client(main_client, true, "canceling idle client"); + bool res; disconnect_client(req, false, "cancel req for idle client"); + + /* let administrative cancel be handled elsewhere */ + if (main_client->pool->admin) { + admin_handle_cancel(main_client); + return; + } + + /* notify readiness */ + SEND_ReadyForQuery(res, main_client); + if (!res) + disconnect_client(main_client, true, + "ReadyForQuery for main_client failed"); return; }