예제 #1
0
def test_encode():
    """
    Test encoding of a message into 'RecordIO' format.
    """
    try:
        encoder = recordio.Encoder(lambda s: bytes(json.dumps(s), "UTF-8"))
    except Exception as exception:
        raise MesosException(
            "Error instantiating 'RecordIO' encoder: {error}".format(
                error=exception))

    try:
        message = {
            "type": "ATTACH_CONTAINER_OUTPUT",
            "containerId": "123456789"
        }

        encoded = encoder.encode(message)

    except Exception as exception:
        raise MesosException(
            "Error encoding 'RecordIO' message: {error}".format(
                error=exception))

    string = json.dumps(message)
    assert encoded == bytes(str(len(string)) + "\n" + string, "UTF-8")
예제 #2
0
    def decode(self, data):
        """
        Decode a 'RecordIO' formatted message to its original type.

        :param data: an array of 'UTF-8' encoded bytes that make up a
                      partial 'RecordIO' message. Subsequent calls to this
                      function maintain state to build up a full 'RecordIO'
                      message and decode it
        :type data: bytes
        :returns: a list of deserialized messages
        :rtype: list
        """

        if not isinstance(data, bytes):
            raise MesosException("Parameter 'data' must of of type 'bytes'")

        if self.state == self.FAILED:
            raise MesosException("Decoder is in a FAILED state")

        records = []

        for c in data:
            if self.state == self.HEADER:
                if c != ord('\n'):
                    self.buffer += bytes([c])
                    continue

                try:
                    self.length = int(self.buffer.decode("UTF-8"))
                except Exception as exception:
                    self.state = self.FAILED
                    raise MesosException("Failed to decode length"
                                         "'{buffer}': {error}".format(
                                             buffer=self.buffer,
                                             error=exception))

                self.buffer = bytes("", "UTF-8")
                self.state = self.RECORD

                # Note that for 0 length records, we immediately decode.
                if self.length <= 0:
                    records.append(self.deserialize(self.buffer))
                    self.state = self.HEADER

            elif self.state == self.RECORD:
                assert self.length
                assert len(self.buffer) < self.length

                self.buffer += bytes([c])

                if len(self.buffer) == self.length:
                    records.append(self.deserialize(self.buffer))
                    self.buffer = bytes("", "UTF-8")
                    self.state = self.HEADER

        return records
예제 #3
0
def test_encode_decode():
    """
    Test encoding/decoding of a message and records into 'RecordIO' format.
    """
    total_messages = 10

    try:
        encoder = recordio.Encoder(lambda s: bytes(json.dumps(s), "UTF-8"))
    except Exception as exception:
        raise MesosException(
            "Error instantiating 'RecordIO' encoder: {error}".format(
                error=exception))

    try:
        decoder = recordio.Decoder(lambda s: json.loads(s.decode("UTF-8")))
    except Exception as exception:
        raise MesosException(
            "Error instantiating 'RecordIO' decoder: {error}".format(
                error=exception))

    try:
        message = {
            "type": "ATTACH_CONTAINER_OUTPUT",
            "containerId": "123456789"
        }

        encoded = b""
        for _ in range(total_messages):
            encoded += encoder.encode(message)

    except Exception as exception:
        raise MesosException(
            "Error encoding 'RecordIO' message: {error}".format(
                error=exception))

    try:
        all_records = []
        offset = 0
        chunk_size = 5
        while offset < len(encoded):
            records = decoder.decode(encoded[offset:offset + chunk_size])
            all_records.extend(records)
            offset += chunk_size

        assert len(all_records) == total_messages

        for record in all_records:
            assert record == message
    except Exception as exception:
        raise MesosException(
            "Error decoding 'RecordIO' messages: {error}".format(
                error=exception))
예제 #4
0
파일: http.py 프로젝트: saint1989/mesos-1
    def request_json(self,
                     method,
                     timeout=None,
                     auth=None,
                     payload=None,
                     decoder=None,
                     params=None,
                     **kwargs):
        """
        Make an HTTP request and deserialize the response as JSON. Optionally
        decode the deserialized json dict into a decoded object.

        :param method: request method
        :type method: str
        :param timeout: timeout in seconds
        :type timeout: float
        :param auth: auth scheme for the request
        :type auth: requests.auth.AuthBase
        :param payload: json payload in the request
        :type payload: dict[str, T] | str
        :param decoder: decoder for json response
        :type decoder: (dict) -> T
        :param params: additional params to include in the request
        :type params: str | dict[str, T]
        :param kwargs: additional arguments to pass to requests.request
        :type kwargs: dict[str, T]
        :return: JSON response
        :rtype: dict[str, T]
        """
        resp = self.request(method=method,
                            timeout=timeout,
                            auth=auth,
                            json=payload,
                            additional_headers=REQUEST_JSON_HEADERS,
                            params=params,
                            **kwargs)

        try:
            json_dict = ujson.loads(resp.text)
        except ValueError as exception:
            raise MesosException(
                'could not load JSON from "{data}"'.format(data=resp.text),
                exception)

        if decoder is not None:
            return decoder(json_dict)

        return json_dict
예제 #5
0
    def encode(self, message):
        """
        Encode a message into 'RecordIO' format.

        :param message: a message to serialize and then wrap in
                        a 'RecordIO' frame.
        :type message: object
        :returns: a serialized message wrapped in a 'RecordIO' frame
        :rtype: bytes
        """

        s = self.serialize(message)

        if not isinstance(s, bytes):
            raise MesosException("Calling 'serialize(message)' must"
                                 " return a 'bytes' object")

        return bytes(str(len(s)) + "\n", "UTF-8") + s
예제 #6
0
파일: http.py 프로젝트: saint1989/mesos-1
    def request(self,
                method,
                additional_headers=None,
                retry=True,
                timeout=None,
                auth=None,
                use_gzip_encoding=None,
                params=None,
                max_attempts=None,
                **kwargs):
        """
        Make an HTTP request by calling self._request with backoff retry.

        :param method: request method
        :type method: str
        :param additional_headers: additional headers to include in the request
        :type additional_headers: dict[str, str]
        :param retry: boolean indicating whether to retry if the request fails
        :type retry: boolean
        :param timeout: timeout in seconds, overrides default_timeout_secs
        :type timeout: float
        :param timeout: timeout in seconds
        :type timeout: float
        :param auth: auth scheme for the request
        :type auth: requests.auth.AuthBase
        :param use_gzip_encoding: boolean indicating whether to pass gzip
                                  encoding in the request headers or not
        :type use_gzip_encoding: boolean | None
        :param params: additional params to include in the request
        :type params: str | dict[str, T] | None
        :param max_attempts: maximum number of attempts to try for any request
        :type max_attempts: int
        :param kwargs: additional arguments to pass to requests.request
        :type kwargs: dict[str, T]
        :return: HTTP response
        :rtype: requests.Response
        """
        request = self._request

        if retry:
            if max_attempts is None:
                max_attempts = self.default_max_attempts

            # We retry only when it makes sense: either due to a network
            # partition (e.g. connection errors) or if the request failed
            # due to a server error such as 500s, timeouts, and so on.
            request = tenacity.retry(
                stop=tenacity.stop_after_attempt(max_attempts),
                wait=tenacity.wait_exponential(),
                retry=tenacity.retry_if_exception_type((
                    requests.exceptions.Timeout,
                    requests.exceptions.ConnectionError,
                    MesosServiceUnavailableException,
                    MesosInternalServerErrorException,
                )),
                reraise=True,
            )(request)

        try:
            return request(method=method,
                           additional_headers=additional_headers,
                           timeout=timeout,
                           auth=auth,
                           use_gzip_encoding=use_gzip_encoding,
                           params=params,
                           **kwargs)
        # If the request itself failed, an exception subclassed from
        # RequestException will be raised. Catch this and reraise as
        # MesosException since we want the caller to be able to catch
        # and handle this.
        except requests.exceptions.RequestException as err:
            raise MesosException('Request failed', err)