diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py
index 10634e43b5daa265209b9425c61939cded442b73..5ab8efb4c426493fa7812dce449c755ae56c8c10 100644
--- a/src/python/grpcio/grpc/_links/service.py
+++ b/src/python/grpcio/grpc/_links/service.py
@@ -337,10 +337,13 @@ class _Kernel(object):
       self._server.start()
       self._server.service(None)
 
-  def graceful_stop(self):
+  def begin_stop(self):
     with self._lock:
       self._server.stop()
       self._server = None
+
+  def end_stop(self):
+    with self._lock:
       self._completion_queue.stop()
       self._completion_queue = None
       pool = self._pool
@@ -348,11 +351,6 @@ class _Kernel(object):
       self._rpc_states = None
     pool.shutdown(wait=True)
 
-  def immediate_stop(self):
-    # TODO(nathaniel): Implementation.
-    raise NotImplementedError(
-        'TODO(nathaniel): after merge of rewritten lower layers')
-
 
 class ServiceLink(links.Link):
   """A links.Link for use on the service-side of a gRPC connection.
@@ -386,18 +384,20 @@ class ServiceLink(links.Link):
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def stop_gracefully(self):
-    """Stops this link.
+  def begin_stop(self):
+    """Indicate imminent link stop and immediate rejection of new RPCs.
 
     New RPCs will be rejected as soon as this method is called, but ongoing RPCs
-    will be allowed to continue until they terminate. This method blocks until
-    all RPCs have terminated.
+    will be allowed to continue until they terminate. This method does not
+    block.
     """
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def stop_immediately(self):
-    """Stops this link.
+  def end_stop(self):
+    """Finishes stopping this link.
+
+    begin_stop must have been called exactly once before calling this method.
 
     All in-progress RPCs will be terminated immediately.
     """
@@ -424,12 +424,11 @@ class _ServiceLink(ServiceLink):
     self._relay.start()
     return self._kernel.start()
 
-  def stop_gracefully(self):
-    self._kernel.graceful_stop()
-    self._relay.stop()
+  def begin_stop(self):
+    self._kernel.begin_stop()
 
-  def stop_immediately(self):
-    self._kernel.immediate_stop()
+  def end_stop(self):
+    self._kernel.end_stop()
     self._relay.stop()
 
 
diff --git a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py
index 7fa90fe35f03b39e3f43e3d6942cea2e6de44f6f..91386f26978f86c9e62f67c7aeca37e306d4f10e 100644
--- a/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py
+++ b/src/python/grpcio_test/grpc_test/_core_over_links_base_interface_test.py
@@ -114,7 +114,8 @@ class _Implementation(test_interfaces.Implementation):
   def destantiate(self, memo):
     invocation_grpc_link, service_grpc_link = memo
     invocation_grpc_link.stop()
-    service_grpc_link.stop_gracefully()
+    service_grpc_link.begin_stop()
+    service_grpc_link.end_stop()
 
   def invocation_initial_metadata(self):
     return _INVOCATION_INITIAL_METADATA
diff --git a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py
index 25b99cbbaf5acb8e7565f3844ea319eef14e62f0..c6190561705cbdde8af6db7d9304473b749d4b0a 100644
--- a/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py
+++ b/src/python/grpcio_test/grpc_test/_crust_over_core_over_links_face_interface_test.py
@@ -121,8 +121,9 @@ class _Implementation(test_interfaces.Implementation):
      service_end_link, pool) = memo
     invocation_end_link.stop(0).wait()
     invocation_grpc_link.stop()
-    service_grpc_link.stop_gracefully()
+    service_grpc_link.begin_stop()
     service_end_link.stop(0).wait()
+    service_grpc_link.end_stop()
     invocation_end_link.join_link(utilities.NULL_LINK)
     invocation_grpc_link.join_link(utilities.NULL_LINK)
     service_grpc_link.join_link(utilities.NULL_LINK)
diff --git a/src/python/grpcio_test/grpc_test/_links/_transmission_test.py b/src/python/grpcio_test/grpc_test/_links/_transmission_test.py
index db011bca66d77a08dc33ef4acb5d9d473352c080..616d8a670d65b97fba9a8a495702101c9d5e73fe 100644
--- a/src/python/grpcio_test/grpc_test/_links/_transmission_test.py
+++ b/src/python/grpcio_test/grpc_test/_links/_transmission_test.py
@@ -62,7 +62,8 @@ class TransmissionTest(test_cases.TransmissionTest, unittest.TestCase):
 
   def destroy_transmitting_links(self, invocation_side_link, service_side_link):
     invocation_side_link.stop()
-    service_side_link.stop_gracefully()
+    service_side_link.begin_stop()
+    service_side_link.end_stop()
 
   def create_invocation_initial_metadata(self):
     return (
@@ -140,7 +141,8 @@ class RoundTripTest(unittest.TestCase):
     invocation_mate.block_until_tickets_satisfy(test_cases.terminated)
 
     invocation_link.stop()
-    service_link.stop_gracefully()
+    service_link.begin_stop()
+    service_link.end_stop()
 
     self.assertIs(
         service_mate.tickets()[-1].termination,
@@ -206,7 +208,8 @@ class RoundTripTest(unittest.TestCase):
     invocation_mate.block_until_tickets_satisfy(test_cases.terminated)
 
     invocation_link.stop()
-    service_link.stop_gracefully()
+    service_link.begin_stop()
+    service_link.end_stop()
 
     observed_requests = tuple(
         ticket.payload for ticket in service_mate.tickets()