From the given socket, reads and yields payload of the given size. With sockets, we don't receive all data at
    once. Therefore this method will yield each time we read some data from the socket until the payload_size has
    reached or socket has no more data.

    Parameters
    ----------
    socket
        Socket to read from

    payload_size : int
        Size of the payload to read. Exactly these many bytes are read from the socket before stopping the yield.

    Yields
    -------
    int
        Type of the stream (1 => stdout, 2 => stderr)
    str
        Data in the stream

def _read_payload(socket, payload_size):
    """
    From the given socket, reads and yields payload of the given size. With sockets, we don't receive all data at
    once. Therefore this method will yield each time we read some data from the socket until the payload_size has
    reached or socket has no more data.

    Parameters
    ----------
    socket
        Socket to read from

    payload_size : int
        Size of the payload to read. Exactly these many bytes are read from the socket before stopping the yield.

    Yields
    -------
    int
        Type of the stream (1 => stdout, 2 => stderr)
    str
        Data in the stream
    """

    remaining = payload_size
    while remaining > 0:

        # Try and read as much as possible
        data = read(socket, remaining)
        if data is None:
            # ``read`` will terminate with an empty string. This is just a transient state where we didn't get any data
            continue

        if len(data) == 0:  # pylint: disable=C1801
            # Empty string. Socket does not have any more data. We are done here even if we haven't read full payload
            break

        remaining -= len(data)
        yield data