def __read_frame(self):
        """*Attempt* to read a frame. If we get an EAGAIN on the frame header, 
        it'll raise to our caller. If we get it *after* we already got the 
        header, wait-out the rest of the frame.
        """

        if self.__frame_header_cache is None:
            _logger.debug("Reading frame header.")
            (length, frame_type) = struct.unpack('!II', self.__read(8))
            self.__frame_header_cache = (length, frame_type)
        else:
            (length, frame_type) = self.__frame_header_cache

        try:
            data = self.__read(length - 4)
        except errno.EAGAIN:
            self.__frame_header_cache = (length, frame_type)
            raise

        self.__frame_header_cache = None
        self.__process_message(frame_type, data)