From e194ff010691458bc300b59f957e38740bd188c3 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Mon, 29 Aug 2016 15:48:41 -0700
Subject: [PATCH] Add transport op debugging, coalesce set_accept_stream &
 send_goaway calls

---
 .../chttp2/transport/chttp2_transport.c       |  7 ++
 src/core/lib/surface/server.c                 |  9 +--
 src/core/lib/transport/transport.h            |  1 +
 src/core/lib/transport/transport_op_string.c  | 77 +++++++++++++++++++
 4 files changed, 86 insertions(+), 8 deletions(-)

diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 3fbfc277e0..03b313ff4c 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -1095,6 +1095,10 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
   grpc_chttp2_transport *t = op->transport_private.args[0];
   grpc_error *close_transport = op->disconnect_with_error;
 
+  char *msg = grpc_transport_op_string(op);
+  gpr_log(GPR_DEBUG, "run:%p: %s", t, msg);
+  gpr_free(msg);
+
   if (op->on_connectivity_state_change != NULL) {
     grpc_connectivity_state_notify_on_state_change(
         exec_ctx, &t->channel_callback.state_tracker, op->connectivity_state,
@@ -1143,6 +1147,9 @@ static void perform_transport_op_locked(grpc_exec_ctx *exec_ctx,
 static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                                  grpc_transport_op *op) {
   grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt;
+  char *msg = grpc_transport_op_string(op);
+  gpr_log(GPR_DEBUG, "scd:%p: %s", t, msg);
+  gpr_free(msg);
   op->transport_private.args[0] = gt;
   grpc_closure_init(&op->transport_private.closure, perform_transport_op_locked,
                     op);
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index fa48764a1c..dbeda55435 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -279,6 +279,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
   grpc_channel_element *elem;
 
   op->send_goaway = send_goaway;
+  op->set_accept_stream = true;
   sc->slice = gpr_slice_from_copied_string("Server shutdown");
   op->goaway_message = &sc->slice;
   op->goaway_status = GRPC_STATUS_OK;
@@ -438,14 +439,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand,
   chand->finish_destroy_channel_closure.cb = finish_destroy_channel;
   chand->finish_destroy_channel_closure.cb_arg = chand;
 
-  grpc_transport_op *op =
-      grpc_make_transport_op(&chand->finish_destroy_channel_closure);
-  op->set_accept_stream = true;
-  grpc_channel_next_op(exec_ctx,
-                       grpc_channel_stack_element(
-                           grpc_channel_get_channel_stack(chand->channel), 0),
-                       op);
-
   if (error != GRPC_ERROR_NONE) {
     const char *msg = grpc_error_string(error);
     gpr_log(GPR_INFO, "Disconnected client: %s", msg);
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 2c1cc3ee42..fe47fea306 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -251,6 +251,7 @@ void grpc_transport_stream_op_add_close(grpc_transport_stream_op *op,
                                         gpr_slice *optional_message);
 
 char *grpc_transport_stream_op_string(grpc_transport_stream_op *op);
+char *grpc_transport_op_string(grpc_transport_op *op);
 
 /* Send a batch of operations on a transport
 
diff --git a/src/core/lib/transport/transport_op_string.c b/src/core/lib/transport/transport_op_string.c
index 138591db2a..f4e758f83b 100644
--- a/src/core/lib/transport/transport_op_string.c
+++ b/src/core/lib/transport/transport_op_string.c
@@ -41,6 +41,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 #include "src/core/lib/support/string.h"
+#include "src/core/lib/transport/connectivity_state.h"
 
 /* These routines are here to facilitate debugging - they produce string
    representations of various transport data structures */
@@ -143,6 +144,82 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) {
   return out;
 }
 
+char *grpc_transport_op_string(grpc_transport_op *op) {
+  char *tmp;
+  char *out;
+  int first = 1;
+
+  gpr_strvec b;
+  gpr_strvec_init(&b);
+
+  if (op->on_connectivity_state_change != NULL) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    if (op->connectivity_state != NULL) {
+      gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:from=%s",
+                   op->on_connectivity_state_change,
+                   grpc_connectivity_state_name(*op->connectivity_state));
+      gpr_strvec_add(&b, tmp);
+    } else {
+      gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE[p=%p]",
+                   op->on_connectivity_state_change);
+      gpr_strvec_add(&b, tmp);
+    }
+  }
+
+  if (op->disconnect_with_error != GRPC_ERROR_NONE) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    const char *err = grpc_error_string(op->disconnect_with_error);
+    gpr_asprintf(&tmp, "DISCONNECT:%s", err);
+    gpr_strvec_add(&b, tmp);
+    grpc_error_free_string(err);
+  }
+
+  if (op->send_goaway) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    char *msg = op->goaway_message == NULL
+                    ? "null"
+                    : gpr_dump_slice(*op->goaway_message,
+                                     GPR_DUMP_ASCII | GPR_DUMP_HEX);
+    gpr_asprintf(&tmp, "SEND_GOAWAY:status=%d:msg=%s", op->goaway_status, msg);
+    if (op->goaway_message != NULL) gpr_free(msg);
+    gpr_strvec_add(&b, tmp);
+  }
+
+  if (op->set_accept_stream) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    gpr_asprintf(&tmp, "SET_ACCEPT_STREAM:%p(%p,...)", op->set_accept_stream_fn,
+                 op->set_accept_stream_user_data);
+    gpr_strvec_add(&b, tmp);
+  }
+
+  if (op->bind_pollset != NULL) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET"));
+  }
+
+  if (op->bind_pollset_set != NULL) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET_SET"));
+  }
+
+  if (op->send_ping != NULL) {
+    if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
+    first = 0;
+    gpr_strvec_add(&b, gpr_strdup("SEND_PING"));
+  }
+
+  out = gpr_strvec_flatten(&b, NULL);
+  gpr_strvec_destroy(&b);
+
+  return out;
+}
+
 void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
                       grpc_call_element *elem, grpc_transport_stream_op *op) {
   char *str = grpc_transport_stream_op_string(op);
-- 
GitLab