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

  callMVar_ :: MVar Call,
  initialMDRef :: !(IORef (Maybe [Metadata])),
  trailingMDRef :: !(IORef (Maybe [Metadata])),
  statusFromServer :: !(IORef (Maybe RpcStatus))
}

newClientReaderWriter :: ClientContext -> MVar Call -> IO ClientReaderWriter
newClientReaderWriter ctx mcall = do
  initMD <- newIORef Nothing
  trailMD <- newIORef Nothing
  status <- newIORef Nothing
  return (ClientReaderWriter ctx mcall initMD trailMD status)

data OpX = forall t. OpX (OpT t)

    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
  status <- clientRWOp (tryReadMVar . statusFromServer)
  case status of
    Nothing -> joinClientRWOp clientWaitForInitialMetadata
    Just (RpcStatus md _ _) -> do
      return md

waitForStatus :: Rpc req resp RpcStatus
waitForStatus = do
  status <- clientRWOp (tryReadMVar . statusFromServer)
  case status of
    Nothing -> joinClientRWOp clientWaitForStatus
    Just status' -> return status'

receiveMessage :: Rpc req resp (Maybe resp)
receiveMessage = do
  abortIfStatus
  msg <- joinClientRWOp clientRead
  case msg of
    Nothing -> return Nothing
    Just x -> do
