From 59c9f904bfe5a9cc7102b44c9440a5e93fdaf159 Mon Sep 17 00:00:00 2001
From: "Mark D. Roth" <roth@google.com>
Date: Wed, 28 Sep 2016 13:33:21 -0700
Subject: [PATCH] Rename GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY to
 GRPC_INITIAL_METADATA_WAIT_FOR_READY. Also add a flag to indicate whether
 wait_for_ready was explicitly set by the application.

---
 include/grpc++/impl/codegen/client_context.h |  6 ++++--
 include/grpc/impl/codegen/grpc_types.h       | 13 ++++++++++---
 src/core/ext/client_config/client_channel.c  |  4 ++--
 src/cpp/client/client_context.cc             |  1 +
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index faabddecc3..dd37e6a850 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -229,10 +229,11 @@ class ClientContext {
   /// EXPERIMENTAL: Trigger wait-for-ready or not on this request
   void set_wait_for_ready(bool wait_for_ready) {
     wait_for_ready_ = wait_for_ready;
+    wait_for_ready_explicitly_set_ = true;
   }
 
   /// DEPRECATED: Use set_wait_for_ready() instead.
-  void set_fail_fast(bool fail_fast) { wait_for_ready_ = !fail_fast; }
+  void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); }
 
 #ifndef GRPC_CXX0X_NO_CHRONO
   /// Return the deadline for the client call.
@@ -352,7 +353,7 @@ class ClientContext {
 
   uint32_t initial_metadata_flags() const {
     return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
-           (wait_for_ready_ ? GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY : 0) |
+           (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) |
            (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0);
   }
 
@@ -360,6 +361,7 @@ class ClientContext {
 
   bool initial_metadata_received_;
   bool wait_for_ready_;
+  bool wait_for_ready_explicitly_set_;
   bool idempotent_;
   bool cacheable_;
   std::shared_ptr<Channel> channel_;
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 191cdd0e5f..e9da7e8b71 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -254,15 +254,22 @@ typedef enum grpc_call_error {
 /** Signal that the call is idempotent */
 #define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u)
 /** Signal that the call should not return UNAVAILABLE before it has started */
-#define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY (0x00000020u)
+#define GRPC_INITIAL_METADATA_WAIT_FOR_READY (0x00000020u)
+/** DEPRECATED: for backward compatibility */
+#define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY \
+    GRPC_INITIAL_METADATA_WAIT_FOR_READY
 /** Signal that the call is cacheable. GRPC is free to use GET verb */
 #define GRPC_INITIAL_METADATA_CACHEABLE_REQUEST (0x00000040u)
+/** Signal that GRPC_INITIAL_METADATA_WAIT_FOR_READY was explicitly set
+    by the calling application. */
+#define GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET (0x00000080u)
 
 /** Mask of all valid flags */
 #define GRPC_INITIAL_METADATA_USED_MASK        \
   (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST |  \
-   GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY | \
-   GRPC_INITIAL_METADATA_CACHEABLE_REQUEST)
+   GRPC_INITIAL_METADATA_WAIT_FOR_READY | \
+   GRPC_INITIAL_METADATA_CACHEABLE_REQUEST | \
+   GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)
 
 /** A single metadata element */
 typedef struct grpc_metadata {
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index b2b4fea83c..2c8113c1db 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -110,10 +110,10 @@ static void set_channel_connectivity_state_locked(grpc_exec_ctx *exec_ctx,
   if ((state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
        state == GRPC_CHANNEL_SHUTDOWN) &&
       chand->lb_policy != NULL) {
-    /* cancel fail-fast picks */
+    /* cancel picks with wait_for_ready=false */
     grpc_lb_policy_cancel_picks(
         exec_ctx, chand->lb_policy,
-        /* mask= */ GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY,
+        /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
         /* check= */ 0);
   }
   grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, state, error,
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index fb9a7c0459..b6008f47b1 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -60,6 +60,7 @@ static ClientContext::GlobalCallbacks* g_client_callbacks =
 ClientContext::ClientContext()
     : initial_metadata_received_(false),
       wait_for_ready_(false),
+      wait_for_ready_explicitly_set_(false),
       idempotent_(false),
       cacheable_(false),
       call_(nullptr),
-- 
GitLab