diff --git a/Makefile b/Makefile
index 44028fcbe6a3029176e9cab4d8e87b324a697df8..633309d9b65cc2830980f1b1c896b88da4ae2d40 100644
--- a/Makefile
+++ b/Makefile
@@ -8286,8 +8286,8 @@ PUBLIC_HEADERS_C += \
 
 LIBARES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBARES_SRC))))
 
-$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DHAVE_CONFIG_H
-$(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion -Wno-invalid-source-encoding
+$(LIBARES_OBJS): CPPFLAGS += -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux) $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
+$(LIBARES_OBJS): CFLAGS += -Wno-sign-conversion $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
 
 $(LIBDIR)/$(CONFIG)/libares.a: $(ZLIB_DEP)  $(LIBARES_OBJS) 
 	$(E) "[AR]      Creating $@"
diff --git a/Rakefile b/Rakefile
index cc02aa130aba4ccc4ed02c4b50edf2441b9cf0f8..7f8d3a2f4acb418de7eba6adba38a8d0899e9bd5 100755
--- a/Rakefile
+++ b/Rakefile
@@ -80,7 +80,7 @@ task 'dlls' do
   grpc_config = ENV['GRPC_CONFIG'] || 'opt'
   verbose = ENV['V'] || '0'
 
-  env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result" '
+  env = 'CPPFLAGS="-D_WIN32_WINNT=0x600 -DUNICODE -D_UNICODE -Wno-unused-variable -Wno-unused-result -DCARES_STATICLIB" '
   env += 'LDFLAGS=-static '
   env += 'SYSTEM=MINGW32 '
   env += 'EMBED_ZLIB=true '
diff --git a/binding.gyp b/binding.gyp
index 27675b4d66dd9d74f8f67cdc609a3bf0954f2d35..2fab58ef1eb982235feec4e65a583483c44002ac 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -39,15 +39,16 @@
 {
   'variables': {
     'runtime%': 'node',
-    # UV integration in C core is enabled by default. It can be disabled
-    # by setting this argument to anything else.
-    'grpc_uv%': 'true',
     # Some Node installations use the system installation of OpenSSL, and on
     # some systems, the system OpenSSL still does not have ALPN support. This
     # will let users recompile gRPC to work without ALPN.
     'grpc_alpn%': 'true',
     # Indicates that the library should be built with gcov.
-    'grpc_gcov%': 'false'
+    'grpc_gcov%': 'false',
+    # Indicates that the library should be built with compatibility for musl
+    # libc, so that it can run on Alpine Linux. This is only necessary if not
+    # building on Alpine Linux
+    'grpc_alpine%': 'false'
   },
   'target_defaults': {
     'configurations': {
@@ -86,17 +87,11 @@
       'include'
     ],
     'defines': [
-      'GPR_BACKWARDS_COMPATIBILITY_MODE'
+      'GPR_BACKWARDS_COMPATIBILITY_MODE',
+      'GRPC_ARES=0',
+      'GRPC_UV'
     ],
     'conditions': [
-      ['grpc_uv=="true"', {
-        'defines': [
-          'GRPC_ARES=0',
-          # Disabling this while bugs are ironed out. Uncomment this to
-          # re-enable libuv integration in C core.
-          'GRPC_UV'
-        ]
-      }],
       ['grpc_gcov=="true"', {
         'cflags': [
             '-O0',
@@ -115,6 +110,11 @@
             '-rdynamic',
         ],
       }],
+      ['grpc_alpine=="true"', {
+        'defines': [
+          'GPR_MUSL_LIBC_COMPAT'
+        ]
+      }],
       ['OS!="win" and runtime=="electron"', {
         "defines": [
           'OPENSSL_NO_THREADS'
@@ -535,6 +535,10 @@
             }
           ]
         },
+      ]
+    }],
+    ['OS == "win"', {
+      'targets': [
         # Only want to compile zlib under Windows
         {
           'cflags': [
@@ -569,7 +573,6 @@
     }]
   ],
   'targets': [
-
     {
       'cflags': [
         '-std=c99',
@@ -648,7 +651,6 @@
       'type': 'static_library',
       'dependencies': [
         'gpr',
-        'node_modules/cares/deps/cares/cares.gyp:cares',
       ],
       'sources': [
         'src/core/lib/surface/init.c',
@@ -943,20 +945,16 @@
         "src/node/ext/call_credentials.cc",
         "src/node/ext/channel.cc",
         "src/node/ext/channel_credentials.cc",
-        "src/node/ext/completion_queue_threadpool.cc",
-        "src/node/ext/completion_queue_uv.cc",
+        "src/node/ext/completion_queue.cc",
         "src/node/ext/node_grpc.cc",
         "src/node/ext/server.cc",
         "src/node/ext/server_credentials.cc",
-        "src/node/ext/server_generic.cc",
-        "src/node/ext/server_uv.cc",
         "src/node/ext/slice.cc",
         "src/node/ext/timeval.cc",
       ],
       "dependencies": [
         "grpc",
         "gpr",
-        "node_modules/cares/deps/cares/cares.gyp:cares",
       ]
     },
     {
diff --git a/build.yaml b/build.yaml
index 941aedc222428d17b78bb78bca6aefe8216bc2e2..ab176b6783cfb3b243b6596cfd0054161d67d604 100644
--- a/build.yaml
+++ b/build.yaml
@@ -4514,10 +4514,11 @@ configs:
       UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=tools/ubsan_suppressions.txt
 defaults:
   ares:
-    CFLAGS: -Wno-sign-conversion -Wno-invalid-source-encoding
+    CFLAGS: -Wno-sign-conversion $(if $(subst MINGW32,,$(SYSTEM)),-Wno-invalid-source-encoding,)
     CPPFLAGS: -Ithird_party/cares -Ithird_party/cares/cares $(if $(subst Linux,,$(SYSTEM)),,-Ithird_party/cares/config_linux)
       $(if $(subst Darwin,,$(SYSTEM)),,-Ithird_party/cares/config_darwin) -fvisibility=hidden
-      -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DHAVE_CONFIG_H
+      -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX $(if $(subst
+      MINGW32,,$(SYSTEM)),-DHAVE_CONFIG_H,)
   benchmark:
     CPPFLAGS: -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
   boringssl:
@@ -4563,13 +4564,10 @@ node_modules:
   - src/node/ext/call_credentials.cc
   - src/node/ext/channel.cc
   - src/node/ext/channel_credentials.cc
-  - src/node/ext/completion_queue_threadpool.cc
-  - src/node/ext/completion_queue_uv.cc
+  - src/node/ext/completion_queue.cc
   - src/node/ext/node_grpc.cc
   - src/node/ext/server.cc
   - src/node/ext/server_credentials.cc
-  - src/node/ext/server_generic.cc
-  - src/node/ext/server_uv.cc
   - src/node/ext/slice.cc
   - src/node/ext/timeval.cc
 openssl_fallback:
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index e12f6f4e9982d51d9ae8c417a289f296cb3e948d..14e348fadb2e31616deb5771ef5eafe22843f43a 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -189,7 +189,7 @@
 #ifdef __GLIBC__
 #define GPR_POSIX_CRASH_HANDLER 1
 #else /* musl libc */
-#define GRPC_MSG_IOVLEN_TYPE int
+#define GPR_MUSL_LIBC_COMPAT 1
 #endif
 #elif defined(__APPLE__)
 #include <Availability.h>
diff --git a/package.json b/package.json
index 6a01ae23243f086981ee025cfbb73d5ca48009f7..e1499a089cd05425c65ad5a695068ddd6e0fe0af 100644
--- a/package.json
+++ b/package.json
@@ -34,8 +34,7 @@
     "lodash": "^4.15.0",
     "nan": "^2.0.0",
     "node-pre-gyp": "^0.6.0",
-    "protobufjs": "^6.7.0",
-    "cares": "^1.1.5"
+    "protobufjs": "^6.7.0"
   },
   "devDependencies": {
     "async": "^2.0.1",
diff --git a/setup.py b/setup.py
index 4cbd1a45a9077a6a86a06a8c7a54cfe1c17fffe0..18ba802fb0f8762777b128546a5b4156e10b7179 100644
--- a/setup.py
+++ b/setup.py
@@ -144,6 +144,8 @@ CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',)
 CYTHON_HELPER_C_FILES = ()
 
 CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES)
+if "win32" in sys.platform and "64bit" in platform.architecture()[0]:
+  CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES)
 
 EXTENSION_INCLUDE_DIRECTORIES = (
     (PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE + ZLIB_INCLUDE +
@@ -163,7 +165,9 @@ DEFINE_MACROS = (
 if "win32" in sys.platform:
   DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1), ('CARES_STATICLIB', 1),)
   if '64bit' in platform.architecture()[0]:
-    DEFINE_MACROS += (('MS_WIN64', 1),)
+    # TODO(zyc): Re-enble c-ares on x64 windows after fixing the
+    # ares_library_init compilation issue
+    DEFINE_MACROS += (('MS_WIN64', 1), ('GRPC_ARES', 0),)
   elif sys.version_info >= (3, 5):
     # For some reason, this is needed to get access to inet_pton/inet_ntop
     # on msvc, but only for 32 bits
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index d3e71625d6556a2167804335f554d1326a762e57..a1a0258c68012fee6723f358a00cdc87402c9960 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -804,6 +804,12 @@ void PrintHeaderService(grpc_generator::Printer *printer,
                  " public:\n");
   printer->Indent();
 
+  // Service metadata
+  printer->Print(*vars,
+                 "static constexpr char const* service_full_name() {\n"
+                 "  return \"$Package$$Service$\";\n"
+                 "}\n");
+
   // Client side
   printer->Print(
       "class StubInterface {\n"
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
index cdec7a1a0202790765f030b1c6e7b4f9e799e9cc..b7c0e929b7e025c6e949c4dce9efa5614010c406 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
@@ -917,8 +917,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(glb_policy->cc_factory != NULL);
 
   arg = grpc_channel_args_find(args->args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
-  glb_policy->lb_call_timeout_ms = grpc_channel_arg_get_integer(
-      arg, (grpc_integer_options){0, 0, INT_MAX});
+  glb_policy->lb_call_timeout_ms =
+      grpc_channel_arg_get_integer(arg, (grpc_integer_options){0, 0, INT_MAX});
 
   // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
   // since we use this to trigger the client_load_reporting filter.
@@ -1279,10 +1279,10 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
   grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
   gpr_timespec deadline =
       glb_policy->lb_call_timeout_ms == 0
-      ? gpr_inf_future(GPR_CLOCK_MONOTONIC)
-      : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
-                     gpr_time_from_millis(glb_policy->lb_call_timeout_ms,
-                                          GPR_TIMESPAN));
+          ? gpr_inf_future(GPR_CLOCK_MONOTONIC)
+          : gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
+                         gpr_time_from_millis(glb_policy->lb_call_timeout_ms,
+                                              GPR_TIMESPAN));
   glb_policy->lb_call = grpc_channel_create_pollset_set_call(
       exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
       glb_policy->base.interested_parties,
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index d4e89d6a6cbc5017cf1429889861736b49288fda..67974b0b6a696743531ff41f9255b74d5fcf31f5 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -886,6 +886,10 @@ static bool op_can_be_run(grpc_transport_stream_op_batch *curr_op,
                !stream_state->state_op_done[OP_RECV_MESSAGE]) {
       CRONET_LOG(GPR_DEBUG, "Because");
       result = false;
+    } else if (curr_op->cancel_stream &&
+               !stream_state->state_callback_received[OP_CANCELED]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
     } else if (curr_op->recv_trailing_metadata) {
       /* We aren't done with trailing metadata yet */
       if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index 269dc35003e18d927a9033b1cfb5ec8ca9e06242..2a553f41149088e644db7b0da7478db97d5111de 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -88,6 +88,7 @@
 #ifndef __GLIBC__
 #define GRPC_LINUX_EPOLL 1
 #define GRPC_LINUX_EVENTFD 1
+#define GRPC_MSG_IOVLEN_TYPE int
 #endif
 #ifndef GRPC_LINUX_EVENTFD
 #define GRPC_POSIX_NO_SPECIAL_WAKEUP_FD 1
diff --git a/src/core/lib/support/cpu_linux.c b/src/core/lib/support/cpu_linux.c
index 1e50f59823fa2022c11048b6a1551e959b5b62d3..b826dde16013da9642fb421061fde793c4257947 100644
--- a/src/core/lib/support/cpu_linux.c
+++ b/src/core/lib/support/cpu_linux.c
@@ -67,16 +67,16 @@ unsigned gpr_cpu_num_cores(void) {
 }
 
 unsigned gpr_cpu_current_cpu(void) {
-#ifdef __GLIBC__
+#ifdef GPR_MUSL_LIBC_COMPAT
+  // sched_getcpu() is undefined on musl
+  return 0;
+#else
   int cpu = sched_getcpu();
   if (cpu < 0) {
     gpr_log(GPR_ERROR, "Error determining current CPU: %s\n", strerror(errno));
     return 0;
   }
   return (unsigned)cpu;
-#else
-  // sched_getcpu() is undefined on musl
-  return 0;
 #endif
 }
 
diff --git a/src/core/lib/support/wrap_memcpy.c b/src/core/lib/support/wrap_memcpy.c
index 050cc6db5ec3cb2f89b2d56429d741d1023a346a..deb8d6b198a00253ee38ef6628dc42a49c705dda 100644
--- a/src/core/lib/support/wrap_memcpy.c
+++ b/src/core/lib/support/wrap_memcpy.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <grpc/support/port_platform.h>
+
 #include <string.h>
 
 /* Provide a wrapped memcpy for targets that need to be backwards
@@ -40,7 +42,7 @@
  */
 
 #ifdef __linux__
-#if defined(__x86_64__) && defined(__GNU_LIBRARY__)
+#if defined(__x86_64__) && !defined(GPR_MUSL_LIBC_COMPAT)
 __asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
 void *__wrap_memcpy(void *destination, const void *source, size_t num) {
   return memcpy(destination, source, num);
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index fe0c80e64219256171a347a2eb15f90a577828b3..49179ab359688083a4035a94f05f0c27fc9585ba 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -42,7 +42,6 @@
 #include "call_credentials.h"
 #include "channel.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "grpc/support/alloc.h"
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index be04cf421d6f89d5b521878a51a4c309c3b0584c..eb6bc0f53feb9c3e48c497d6762fb35a2fa65302 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -41,7 +41,6 @@
 #include "channel.h"
 #include "channel_credentials.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "timeval.h"
diff --git a/src/node/ext/completion_queue_uv.cc b/src/node/ext/completion_queue.cc
similarity index 98%
rename from src/node/ext/completion_queue_uv.cc
rename to src/node/ext/completion_queue.cc
index 9b60911d1e9653c2d9ead7995359cc9c40fa9c86..d01abad7572491fe6fdf818f793247dca60f1492 100644
--- a/src/node/ext/completion_queue_uv.cc
+++ b/src/node/ext/completion_queue.cc
@@ -31,8 +31,6 @@
  *
  */
 
-#ifdef GRPC_UV
-
 #include <grpc/grpc.h>
 #include <node.h>
 #include <uv.h>
@@ -95,5 +93,3 @@ void CompletionQueueInit(Local<Object> exports) {
 
 }  // namespace node
 }  // namespace grpc
-
-#endif /* GRPC_UV */
diff --git a/src/node/ext/completion_queue_async_worker.h b/src/node/ext/completion_queue_async_worker.h
deleted file mode 100644
index 6e541167658aefd4c88c92394c0bafe83a2dfb14..0000000000000000000000000000000000000000
--- a/src/node/ext/completion_queue_async_worker.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
-#define NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
-#include <nan.h>
-
-#include "grpc/grpc.h"
-
-namespace grpc {
-namespace node {
-
-/* A worker that asynchronously calls completion_queue_next, and queues onto the
-   node event loop a call to the function stored in the event's tag. */
-class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
- public:
-  CompletionQueueAsyncWorker();
-
-  ~CompletionQueueAsyncWorker();
-  /* Calls completion_queue_next with the provided deadline, and stores the
-     event if there was one or sets an error message if there was not */
-  void Execute();
-
-  /* Returns the completion queue attached to this class */
-  static grpc_completion_queue *GetQueue();
-
-  /* Convenience function to create a worker with the given arguments and queue
-     it to run asynchronously */
-  static void Next();
-
-  /* Initialize the CompletionQueueAsyncWorker class */
-  static void Init(v8::Local<v8::Object> exports);
-
- protected:
-  /* Called when Execute has succeeded (completed without setting an error
-     message). Calls the saved callback with the event that came from
-     completion_queue_next */
-  void HandleOKCallback();
-
-  void HandleErrorCallback();
-
- private:
-  grpc_event result;
-
-  static grpc_completion_queue *queue;
-
-  // Number of grpc_completion_queue_next calls in the thread pool
-  static int current_threads;
-  // Number of grpc_completion_queue_next calls waiting to enter the thread pool
-  static int waiting_next_calls;
-};
-
-}  // namespace node
-}  // namespace grpc
-
-#endif  // NET_GRPC_NODE_COMPLETION_QUEUE_ASYNC_WORKER_H_
diff --git a/src/node/ext/completion_queue_threadpool.cc b/src/node/ext/completion_queue_threadpool.cc
deleted file mode 100644
index 72df5d1d65fa9e24121d9ce66a160d6a1f976c18..0000000000000000000000000000000000000000
--- a/src/node/ext/completion_queue_threadpool.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/* I don't like using #ifndef, but I don't see a better way to do this */
-#ifndef GRPC_UV
-
-#include <nan.h>
-#include <node.h>
-
-#include "call.h"
-#include "completion_queue.h"
-#include "grpc/grpc.h"
-#include "grpc/support/log.h"
-#include "grpc/support/time.h"
-
-namespace grpc {
-namespace node {
-
-namespace {
-
-/* A worker that asynchronously calls completion_queue_next, and queues onto the
-   node event loop a call to the function stored in the event's tag. */
-class CompletionQueueAsyncWorker : public Nan::AsyncWorker {
- public:
-  CompletionQueueAsyncWorker();
-
-  ~CompletionQueueAsyncWorker();
-  /* Calls completion_queue_next with the provided deadline, and stores the
-     event if there was one or sets an error message if there was not */
-  void Execute();
-
-  /* Returns the completion queue attached to this class */
-  static grpc_completion_queue *GetQueue();
-
-  /* Convenience function to create a worker with the given arguments and queue
-     it to run asynchronously */
-  static void Next();
-
-  /* Initialize the CompletionQueueAsyncWorker class */
-  static void Init(v8::Local<v8::Object> exports);
-
- protected:
-  /* Called when Execute has succeeded (completed without setting an error
-     message). Calls the saved callback with the event that came from
-     completion_queue_next */
-  void HandleOKCallback();
-
-  void HandleErrorCallback();
-
- private:
-  static void TryAddWorker();
-
-  grpc_event result;
-
-  static grpc_completion_queue *queue;
-
-  // Number of grpc_completion_queue_next calls in the thread pool
-  static int current_threads;
-  // Number of grpc_completion_queue_next calls waiting to enter the thread pool
-  static int waiting_next_calls;
-};
-
-const int max_queue_threads = 2;
-
-using v8::Function;
-using v8::Local;
-using v8::Object;
-using v8::Value;
-
-grpc_completion_queue *CompletionQueueAsyncWorker::queue;
-
-// Invariants: current_threads <= max_queue_threads
-// (current_threads == max_queue_threads) || (waiting_next_calls == 0)
-
-int CompletionQueueAsyncWorker::current_threads;
-int CompletionQueueAsyncWorker::waiting_next_calls;
-
-CompletionQueueAsyncWorker::CompletionQueueAsyncWorker()
-    : Nan::AsyncWorker(NULL) {}
-
-CompletionQueueAsyncWorker::~CompletionQueueAsyncWorker() {}
-
-void CompletionQueueAsyncWorker::Execute() {
-  result = grpc_completion_queue_next(queue, gpr_inf_future(GPR_CLOCK_REALTIME),
-                                      NULL);
-  if (!result.success) {
-    SetErrorMessage("The async function encountered an error");
-  }
-}
-
-grpc_completion_queue *CompletionQueueAsyncWorker::GetQueue() { return queue; }
-
-void CompletionQueueAsyncWorker::TryAddWorker() {
-  if (current_threads < max_queue_threads && waiting_next_calls > 0) {
-    current_threads += 1;
-    waiting_next_calls -= 1;
-    CompletionQueueAsyncWorker *worker = new CompletionQueueAsyncWorker();
-    Nan::AsyncQueueWorker(worker);
-  }
-  GPR_ASSERT(current_threads <= max_queue_threads);
-  GPR_ASSERT((current_threads == max_queue_threads) ||
-             (waiting_next_calls == 0));
-}
-
-void CompletionQueueAsyncWorker::Next() {
-  waiting_next_calls += 1;
-  TryAddWorker();
-}
-
-void CompletionQueueAsyncWorker::Init(Local<Object> exports) {
-  Nan::HandleScope scope;
-  current_threads = 0;
-  waiting_next_calls = 0;
-  queue = grpc_completion_queue_create_for_next(NULL);
-}
-
-void CompletionQueueAsyncWorker::HandleOKCallback() {
-  Nan::HandleScope scope;
-  current_threads -= 1;
-  TryAddWorker();
-  CompleteTag(result.tag, NULL);
-
-  DestroyTag(result.tag);
-}
-
-void CompletionQueueAsyncWorker::HandleErrorCallback() {
-  Nan::HandleScope scope;
-  current_threads -= 1;
-  TryAddWorker();
-  CompleteTag(result.tag, ErrorMessage());
-
-  DestroyTag(result.tag);
-}
-
-}  // namespace
-
-grpc_completion_queue *GetCompletionQueue() {
-  return CompletionQueueAsyncWorker::GetQueue();
-}
-
-void CompletionQueueNext() { CompletionQueueAsyncWorker::Next(); }
-
-void CompletionQueueInit(Local<Object> exports) {
-  CompletionQueueAsyncWorker::Init(exports);
-}
-
-}  // namespace node
-}  // namespace grpc
-
-#endif /* GRPC_UV */
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 076f1ed4242f6fdebe2b1536e345a6e68f922580..e193e82179aa12af62ccf2903bf007104173b613 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -43,18 +43,15 @@
 #include "grpc/support/time.h"
 
 // TODO(murgatroid99): Remove this when the endpoint API becomes public
-#ifdef GRPC_UV
 extern "C" {
 #include "src/core/lib/iomgr/pollset_uv.h"
 }
-#endif
 
 #include "call.h"
 #include "call_credentials.h"
 #include "channel.h"
 #include "channel_credentials.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 #include "server.h"
 #include "server_credentials.h"
 #include "slice.h"
@@ -432,9 +429,7 @@ void init(Local<Object> exports) {
   InitWriteFlags(exports);
   InitLogConstants(exports);
 
-#ifdef GRPC_UV
   grpc_pollset_work_run_loop = 0;
-#endif
 
   grpc::node::Call::Init(exports);
   grpc::node::CallCredentials::Init(exports);
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index 1871a3245287bf277d1ac625e1827d8f1375c294..a885a9f26845605d0ab368e6190a0e9323fda5ff 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -41,7 +41,6 @@
 #include <vector>
 #include "call.h"
 #include "completion_queue.h"
-#include "completion_queue_async_worker.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "grpc/support/log.h"
@@ -78,6 +77,30 @@ using v8::Value;
 Nan::Callback *Server::constructor;
 Persistent<FunctionTemplate> Server::fun_tpl;
 
+static Callback *shutdown_callback = NULL;
+
+class ServerShutdownOp : public Op {
+ public:
+  ServerShutdownOp(grpc_server *server) : server(server) {}
+
+  ~ServerShutdownOp() {}
+
+  Local<Value> GetNodeValue() const { return Nan::Null(); }
+
+  bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
+  bool IsFinalOp() { return false; }
+  void OnComplete(bool success) {
+    /* Because cancel_all_calls was called, we assume that shutdown_and_notify
+       completes successfully */
+    grpc_server_destroy(server);
+  }
+
+  grpc_server *server;
+
+ protected:
+  std::string GetTypeString() const { return "shutdown"; }
+};
+
 class NewCallOp : public Op {
  public:
   NewCallOp() {
@@ -149,6 +172,10 @@ class TryShutdownOp : public Op {
       server_persist;
 };
 
+Server::Server(grpc_server *server) : wrapped_server(server) {}
+
+Server::~Server() { this->ShutdownServer(); }
+
 void Server::Init(Local<Object> exports) {
   HandleScope scope;
   Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
@@ -177,6 +204,36 @@ void Server::DestroyWrappedServer() {
   }
 }
 
+NAN_METHOD(ServerShutdownCallback) {
+  if (!info[0]->IsNull()) {
+    return Nan::ThrowError("forceShutdown failed somehow");
+  }
+}
+
+void Server::ShutdownServer() {
+  Nan::HandleScope scope;
+  if (this->wrapped_server != NULL) {
+    if (shutdown_callback == NULL) {
+      Local<FunctionTemplate> callback_tpl =
+          Nan::New<FunctionTemplate>(ServerShutdownCallback);
+      shutdown_callback =
+          new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
+    }
+
+    ServerShutdownOp *op = new ServerShutdownOp(this->wrapped_server);
+    unique_ptr<OpVec> ops(new OpVec());
+    ops->push_back(unique_ptr<Op>(op));
+
+    grpc_server_shutdown_and_notify(
+        this->wrapped_server, GetCompletionQueue(),
+        new struct tag(new Callback(**shutdown_callback), ops.release(), NULL,
+                       Nan::Null()));
+    grpc_server_cancel_all_calls(this->wrapped_server);
+    CompletionQueueNext();
+    this->wrapped_server = NULL;
+  }
+}
+
 NAN_METHOD(Server::New) {
   /* If this is not a constructor call, make a constructor call and return
      the result */
diff --git a/src/node/ext/server_generic.cc b/src/node/ext/server_generic.cc
deleted file mode 100644
index 088273d527cc0fbf32497288fc7c7e617fc5442e..0000000000000000000000000000000000000000
--- a/src/node/ext/server_generic.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_UV
-
-#include "server.h"
-
-#include <nan.h>
-#include <node.h>
-#include "grpc/grpc.h"
-#include "grpc/support/time.h"
-
-namespace grpc {
-namespace node {
-
-Server::Server(grpc_server *server) : wrapped_server(server) {
-  grpc_completion_queue_attributes attrs = {
-      GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_NON_LISTENING};
-  shutdown_queue = grpc_completion_queue_create(
-      grpc_completion_queue_factory_lookup(&attrs), &attrs, NULL);
-  grpc_server_register_completion_queue(server, shutdown_queue, NULL);
-}
-
-Server::~Server() {
-  this->ShutdownServer();
-  grpc_completion_queue_shutdown(this->shutdown_queue);
-  grpc_completion_queue_destroy(this->shutdown_queue);
-}
-
-void Server::ShutdownServer() {
-  if (this->wrapped_server != NULL) {
-    grpc_server_shutdown_and_notify(this->wrapped_server, this->shutdown_queue,
-                                    NULL);
-    grpc_server_cancel_all_calls(this->wrapped_server);
-    grpc_completion_queue_pluck(this->shutdown_queue, NULL,
-                                gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
-    grpc_server_destroy(this->wrapped_server);
-    this->wrapped_server = NULL;
-  }
-}
-
-}  // namespace grpc
-}  // namespace node
-
-#endif /* GRPC_UV */
diff --git a/src/node/ext/server_uv.cc b/src/node/ext/server_uv.cc
deleted file mode 100644
index 709921b7fc1b207bc90132ce00e28a914f62776c..0000000000000000000000000000000000000000
--- a/src/node/ext/server_uv.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *
- * Copyright 2017, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifdef GRPC_UV
-
-#include "server.h"
-
-#include <nan.h>
-#include <node.h>
-#include "grpc/grpc.h"
-#include "grpc/support/time.h"
-
-#include "call.h"
-#include "completion_queue.h"
-
-namespace grpc {
-namespace node {
-
-using Nan::Callback;
-using Nan::MaybeLocal;
-
-using v8::External;
-using v8::Function;
-using v8::FunctionTemplate;
-using v8::Local;
-using v8::Object;
-using v8::Value;
-
-static Callback *shutdown_callback = NULL;
-
-class ServerShutdownOp : public Op {
- public:
-  ServerShutdownOp(grpc_server *server) : server(server) {}
-
-  ~ServerShutdownOp() {}
-
-  Local<Value> GetNodeValue() const { return Nan::Null(); }
-
-  bool ParseOp(Local<Value> value, grpc_op *out) { return true; }
-  bool IsFinalOp() { return false; }
-  void OnComplete(bool success) {
-    /* Because cancel_all_calls was called, we assume that shutdown_and_notify
-       completes successfully */
-    grpc_server_destroy(server);
-  }
-
-  grpc_server *server;
-
- protected:
-  std::string GetTypeString() const { return "shutdown"; }
-};
-
-Server::Server(grpc_server *server) : wrapped_server(server) {}
-
-Server::~Server() { this->ShutdownServer(); }
-
-NAN_METHOD(ServerShutdownCallback) {
-  if (!info[0]->IsNull()) {
-    return Nan::ThrowError("forceShutdown failed somehow");
-  }
-}
-
-void Server::ShutdownServer() {
-  Nan::HandleScope scope;
-  if (this->wrapped_server != NULL) {
-    if (shutdown_callback == NULL) {
-      Local<FunctionTemplate> callback_tpl =
-          Nan::New<FunctionTemplate>(ServerShutdownCallback);
-      shutdown_callback =
-          new Callback(Nan::GetFunction(callback_tpl).ToLocalChecked());
-    }
-
-    ServerShutdownOp *op = new ServerShutdownOp(this->wrapped_server);
-    unique_ptr<OpVec> ops(new OpVec());
-    ops->push_back(unique_ptr<Op>(op));
-
-    grpc_server_shutdown_and_notify(
-        this->wrapped_server, GetCompletionQueue(),
-        new struct tag(new Callback(**shutdown_callback), ops.release(), NULL,
-                       Nan::Null()));
-    grpc_server_cancel_all_calls(this->wrapped_server);
-    CompletionQueueNext();
-    this->wrapped_server = NULL;
-  }
-}
-
-}  // namespace grpc
-}  // namespace node
-
-#endif /* GRPC_UV */
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index a2e8c588920515df650ce246eebd96f91e880404..933174ab6edb6b12565ad3bd7ec6e7a02177e682 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -41,15 +41,16 @@
   {
     'variables': {
       'runtime%': 'node',
-      # UV integration in C core is enabled by default. It can be disabled
-      # by setting this argument to anything else.
-      'grpc_uv%': 'true',
       # Some Node installations use the system installation of OpenSSL, and on
       # some systems, the system OpenSSL still does not have ALPN support. This
       # will let users recompile gRPC to work without ALPN.
       'grpc_alpn%': 'true',
       # Indicates that the library should be built with gcov.
-      'grpc_gcov%': 'false'
+      'grpc_gcov%': 'false',
+      # Indicates that the library should be built with compatibility for musl
+      # libc, so that it can run on Alpine Linux. This is only necessary if not
+      # building on Alpine Linux
+      'grpc_alpine%': 'false'
     },
     'target_defaults': {
       'configurations': {
@@ -83,17 +84,11 @@
         'include'
       ],
       'defines': [
-        'GPR_BACKWARDS_COMPATIBILITY_MODE'
+        'GPR_BACKWARDS_COMPATIBILITY_MODE',
+        'GRPC_ARES=0',
+        'GRPC_UV'
       ],
       'conditions': [
-        ['grpc_uv=="true"', {
-          'defines': [
-            'GRPC_ARES=0',
-            # Disabling this while bugs are ironed out. Uncomment this to
-            # re-enable libuv integration in C core.
-            'GRPC_UV'
-          ]
-        }],
         ['grpc_gcov=="true"', {
           % for arg, prop in [('CPPFLAGS', 'cflags'), ('DEFINES', 'defines'), ('LDFLAGS', 'ldflags')]:
           %  if configs['gcov'].get(arg, None) is not None:
@@ -105,6 +100,11 @@
           %  endif
           % endfor
         }],
+        ['grpc_alpine=="true"', {
+          'defines': [
+            'GPR_MUSL_LIBC_COMPAT'
+          ]
+        }],
         ['OS!="win" and runtime=="electron"', {
           "defines": [
             'OPENSSL_NO_THREADS'
@@ -233,6 +233,10 @@
               }
             ]
           },
+        ]
+      }],
+      ['OS == "win"', {
+        'targets': [
           # Only want to compile zlib under Windows
           % for module in node_modules:
           % for lib in libs:
@@ -264,13 +268,6 @@
       }]
     ],
     'targets': [
-  <%
-      for lib in libs:
-        if 'grpc' in lib.transitive_deps or lib.name == 'grpc':
-          lib.deps.append('node_modules/cares/deps/cares/cares.gyp:cares')
-      for module in node_modules:
-        module.deps.append('node_modules/cares/deps/cares/cares.gyp:cares')
-  %>
       % for module in node_modules:
       % for lib in libs:
       % if lib.name in module.transitive_deps and lib.name not in ('boringssl', 'z'):
diff --git a/templates/package.json.template b/templates/package.json.template
index b69fd28d2abf3d807c5f26747dbd170f4395de65..3bae8fde430a130dd1f7a459e3d56912f15c2b52 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -36,8 +36,7 @@
       "lodash": "^4.15.0",
       "nan": "^2.0.0",
       "node-pre-gyp": "^0.6.0",
-      "protobufjs": "^6.7.0",
-      "cares": "^1.1.5"
+      "protobufjs": "^6.7.0"
     },
     "devDependencies": {
       "async": "^2.0.1",
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index 8e3ae32a4946a7785fe17d586ff2bf481cf151c1..eb12d371eaf456215c270f8861ebf00d8dafa71d 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -69,6 +69,9 @@ namespace testing {
 // ServiceA leading comment 1
 class ServiceA final {
  public:
+  static constexpr char const* service_full_name() {
+    return "grpc.testing.ServiceA";
+  }
   class StubInterface {
    public:
     virtual ~StubInterface() {}
@@ -373,6 +376,9 @@ class ServiceA final {
 // ServiceB leading comment 1
 class ServiceB final {
  public:
+  static constexpr char const* service_full_name() {
+    return "grpc.testing.ServiceB";
+  }
   class StubInterface {
    public:
     virtual ~StubInterface() {}
diff --git a/third_party/cares/ares_build.h b/third_party/cares/ares_build.h
index 7d69f1e6aecdd5cf729f4006503d7fd43632ccfe..d6b3d49f37f0ab0a47efdb7cf651f9a56cc809d7 100644
--- a/third_party/cares/ares_build.h
+++ b/third_party/cares/ares_build.h
@@ -251,4 +251,14 @@
   typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
 #endif
 
+/* Undefine UNICODE, as c-ares does not use the ANSI version of functions */
+/* explicitly. */
+#ifdef UNICODE
+#  undef UNICODE
+#endif
+
+#ifdef _UNICODE
+#  undef _UNICODE
+#endif
+
 #endif /* __CARES_BUILD_H */
diff --git a/tools/run_tests/artifacts/build_artifact_node.sh b/tools/run_tests/artifacts/build_artifact_node.sh
index 2da2ac5f91927070377288f3303a9718b6e2e2b6..7a747551e88072bc789f12cbc6151c0cba67bfa0 100755
--- a/tools/run_tests/artifacts/build_artifact_node.sh
+++ b/tools/run_tests/artifacts/build_artifact_node.sh
@@ -48,7 +48,7 @@ electron_versions=( 1.0.0 1.1.0 1.2.0 1.3.0 1.4.0 1.5.0 1.6.0 )
 
 for version in ${node_versions[@]}
 do
-  ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH
+  ./node_modules/.bin/node-pre-gyp configure rebuild package testpackage --target=$version --target_arch=$NODE_TARGET_ARCH --grpc_alpine=true
   cp -r build/stage/* artifacts/
 done
 
diff --git a/tools/run_tests/helper_scripts/build_node.sh b/tools/run_tests/helper_scripts/build_node.sh
index 2c4cf02d8fe7d2398b5e2508abb0be67d0ea1a82..07ecf98396aa725b2bb886026e1e1933e7bbfbb1 100755
--- a/tools/run_tests/helper_scripts/build_node.sh
+++ b/tools/run_tests/helper_scripts/build_node.sh
@@ -46,6 +46,4 @@ case "$CONFIG" in
   *) config_flag='--release' ;;
 esac
 
-uv_flag=$2
-
-npm install --unsafe-perm --build-from-source $uv_flag $config_flag
+npm install --unsafe-perm --build-from-source $config_flag
diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh
index 3f7c9fed961d966395d0027729d21867667d724a..5f8749dda2725f9a30b9ced02ef0387d568e5e36 100755
--- a/tools/run_tests/performance/build_performance.sh
+++ b/tools/run_tests/performance/build_performance.sh
@@ -61,9 +61,6 @@ do
   "csharp")
     python tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8 --compiler coreclr
     ;;
-  "node")
-    python tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8 --iomgr_platform=uv
-    ;;
   *)
     python tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8
     ;;
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 4da2ba4c3b0ca2dc0d09a9013e3a960f40cdc9e2..62e92c3d1dd0df8deda3696a6fc502642e347db1 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -430,10 +430,6 @@ class NodeLanguage(object):
     _check_compiler(self.args.compiler, ['default', 'node0.12',
                                          'node4', 'node5', 'node6',
                                          'node7', 'electron1.3', 'electron1.6'])
-    if args.iomgr_platform == "uv":
-      self.use_uv = True
-    else:
-      self.use_uv = False
     if self.args.compiler == 'default':
       self.runtime = 'node'
       self.node_version = '7'
@@ -481,7 +477,6 @@ class NodeLanguage(object):
       else:
         config_flag = '--release'
       return [['tools\\run_tests\\helper_scripts\\build_node.bat',
-               '--grpc_uv={}'.format('true' if self.use_uv else 'false'),
                config_flag]]
     else:
       build_script = 'build_node'
@@ -490,8 +485,7 @@ class NodeLanguage(object):
         # building for electron requires a patch version
         self.node_version += '.0'
       return [['tools/run_tests/helper_scripts/{}.sh'.format(build_script),
-               self.node_version,
-               '--grpc_uv={}'.format('true' if self.use_uv else 'false')]]
+               self.node_version]]
 
   def post_tests_steps(self):
     return []
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 70340cd747d85a524dfbda7bb357db14cb9a38ba..f45bb194a1c86a9d2232aea7f7ee884485dc02b8 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -289,15 +289,6 @@ def _create_portability_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS)
                               platforms=['linux'],
                               arch='default',
                               compiler='electron1.6',
-                              iomgr_platform='uv',
-                              labels=['portability'],
-                              extra_args=extra_args,
-                              inner_jobs=inner_jobs)
-
-  test_jobs += _generate_jobs(languages=['node'],
-                              configs=['dbg'],
-                              platforms=['linux'],
-                              iomgr_platform='uv',
                               labels=['portability'],
                               extra_args=extra_args,
                               inner_jobs=inner_jobs)