]> granicus.if.org Git - pgbouncer/commitdiff
cancel of pause/resume, dont drop idle clients
authorMarko Kreen <markokr@gmail.com>
Wed, 1 Aug 2007 22:00:47 +0000 (22:00 +0000)
committerMarko Kreen <markokr@gmail.com>
Wed, 1 Aug 2007 22:00:47 +0000 (22:00 +0000)
doc/todo.txt
src/admin.c
src/admin.h
src/objects.c

index da65c8622cef10ef2c185cd9f03530921ab66941..c38e1ee40a1f2ec2d7ec05976c37042aa970943c 100644 (file)
@@ -2,7 +2,6 @@
 
 == Small stuff ==
 
- * cancel of SUSPEND/PAUSE
  * suspend_timeout - drop stalled conns
 
 == Low-prio ==
index 2e39bebe66139efcd86303a33944ce7bd7348b0b..4c51129f8a58a3aadb7aeba3c2f01afe27e2c733 100644 (file)
@@ -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");
+}
+
index dcfd14c7fc468d3ff05e8eb644f1697d39f1dde3..6163fa9bcd51a1aff55d81b70b2291d94192228a 100644 (file)
@@ -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);
+
index ebb9b280e41846476d00dd124519cc862b11f4b0..4e3387a518f929bb34af1ff1df27622187db847b 100644 (file)
@@ -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;
        }