     Left err -> return (RpcError err)
     Right a -> return (RpcOk a)
 
+clientRWOp :: (ClientReaderWriter -> IO a) -> Rpc req resp a
+clientRWOp act = do
+  crw <- askCrw
+  liftIO (act crw)
+
+joinClientRWOp :: (ClientReaderWriter -> IO (RpcReply a)) -> Rpc req resp a
+joinClientRWOp act = do
+  x <- clientRWOp act
+  joinReply x
+
+abortIfStatus :: Rpc req resp ()
+abortIfStatus = do
+  status <- clientRWOp (tryReadMVar . statusFromServer)
+  case status of
+    Nothing -> return ()
+    Just (RpcStatus _ code msg) ->
+      -- call has ended. no further batch ops can be executed.
+      -- doesn't have to be an error, could be 200!
+      lift (throwE (StatusError code msg))
+
 initialMetadata :: Rpc req resp [Metadata]
 initialMetadata = do
-  crw <- askCrw
-  joinReply =<< liftIO (clientWaitForInitialMetadata crw)
+  status <- clientRWOp (tryReadMVar . statusFromServer)
+  case status of
+    Nothing -> joinClientRWOp clientWaitForInitialMetadata
+    Just (RpcStatus md _ _) -> do
+      return md
 
 waitForStatus :: Rpc req resp RpcStatus
 waitForStatus = do
-  crw <- askCrw
-  joinReply =<< liftIO (clientWaitForStatus crw)
+  status <- clientRWOp (tryReadMVar . statusFromServer)
+  case status of
+    Nothing -> joinClientRWOp clientWaitForStatus
+    Just status' -> return status'
 
 receiveMessage :: Rpc req resp (Maybe resp)
 receiveMessage = do
-  crw <- askCrw
-  msg <- joinReply =<< liftIO (clientRead crw)
+  abortIfStatus
+  msg <- joinClientRWOp clientRead
   case msg of
     Nothing -> return Nothing
     Just x -> do


clientWaitForStatus :: ClientReaderWriter -> IO (RpcReply RpcStatus)
clientWaitForStatus crw@(ClientReaderWriter{..}) = do
  status <- readIORef statusFromServer
  case status of
    Nothing -> do
      recvStatusOp <- opRecvStatusOnClient crw

      statusDetails <- B.packCString =<< C.peek ptrPtrStatusStr
      let status = RpcStatus trailingMd statusCode statusDetails
      writeIORef value status
      putMVar statusFromServer status
      free
    free = do
      freeMetadataArray trailingMetadataArrPtr
