Returns (batch, data) if one or more items could be retrieved.

        If the cancellation occurs or only invalid items were in the
        queue, (None, None) will be returned instead.

async def get(self):
        """
        Returns (batch, data) if one or more items could be retrieved.

        If the cancellation occurs or only invalid items were in the
        queue, (None, None) will be returned instead.
        """
        if not self._deque:
            self._ready.clear()
            await self._ready.wait()

        buffer = io.BytesIO()
        batch = []
        size = 0

        # Fill a new batch to return while the size is small enough,
        # as long as we don't exceed the maximum length of messages.
        while self._deque and len(batch) <= MessageContainer.MAXIMUM_LENGTH:
            state = self._deque.popleft()
            size += len(state.data) + TLMessage.SIZE_OVERHEAD

            if size <= MessageContainer.MAXIMUM_SIZE:
                state.msg_id = self._state.write_data_as_message(
                    buffer, state.data, isinstance(state.request, TLRequest),
                    after_id=state.after.msg_id if state.after else None
                )
                batch.append(state)
                self._log.debug('Assigned msg_id = %d to %s (%x)',
                                state.msg_id, state.request.__class__.__name__,
                                id(state.request))
                continue

            if batch:
                # Put the item back since it can't be sent in this batch
                self._deque.appendleft(state)
                break

            # If a single message exceeds the maximum size, then the
            # message payload cannot be sent. Telegram would forcibly
            # close the connection; message would never be confirmed.
            #
            # We don't put the item back because it can never be sent.
            # If we did, we would loop again and reach this same path.
            # Setting the exception twice results in `InvalidStateError`
            # and this method should never return with error, which we
            # really want to avoid.
            self._log.warning(
                'Message payload for %s is too long (%d) and cannot be sent',
                state.request.__class__.__name__, len(state.data)
            )
            state.future.set_exception(
                ValueError('Request payload is too big'))

            size = 0
            continue

        if not batch:
            return None, None

        if len(batch) > 1:
            # Inlined code to pack several messages into a container
            data = struct.pack(
                '<Ii', MessageContainer.CONSTRUCTOR_ID, len(batch)
            ) + buffer.getvalue()
            buffer = io.BytesIO()
            container_id = self._state.write_data_as_message(
                buffer, data, content_related=False
            )
            for s in batch:
                s.container_id = container_id

        data = buffer.getvalue()
        return batch, data