code: private byte[] recvFromNodeCheckBigMsg(final NodeStruct node,
                                           final ReefNetworkGroupCommProtos.GroupCommMessage.Type msgType) {
      LOG.entering("OperatorTopologyStructImpl", "recvFromNodeCheckBigMsg", new Object[]{node, msgType});
  
      byte[] retVal = receiveFromNode(node, false);
      if (retVal != null && retVal.length == 0) {
        LOG.finest(getQualifiedName() + " Got msg that node " + node.getId()
            + " has large data and is ready to send it. Sending ACK to receive data.");
        sendToNode(Utils.EMPTY_BYTE_ARR, msgType, node);
        retVal = receiveFromNode(node, true);
  
        if (retVal != null) {
          LOG.finest(getQualifiedName() + " Received large msg from node " + node.getId()
              + ". Will process it after ACKing.");
          sendToNode(Utils.EMPTY_BYTE_ARR, msgType, node);
        } else {
          LOG.warning(getQualifiedName() + "Expected large msg from node " + node.getId()
              + " but received nothing.");
        }
      }
  
      LOG.exiting("OperatorTopologyStructImpl", "recvFromNodeCheckBigMsg");
      return retVal;
    }
docs: Receive data from {@code node}, while checking if it is trying to send a big message.
  Nodes that send big messages will first send an empty data message and
  wait for an ACK before transmitting the actual big message. Thus the
  receiving side checks whether a message is empty or not, and after sending
  an ACK it must wait for another message if the first message was empty.
  
  @param node node to receive a message from
  @param msgType message type
  @return message sent from {@code node}