コード例 #1
0
ファイル: base.py プロジェクト: shayanadc/pikobot
    def _fetch_cmd(self, name, keys, expect_cas):
        if name == b'stats':
            # stats commands can have multiple arguments
            #   `stats cachedump 1 1`
            checked_keys = [self.check_key(k) for k in keys]
            cmd = name + b' ' + b' '.join(checked_keys) + b'\r\n'
        else:
            checked_keys = dict((self.check_key(k), k) for k in keys)
            cmd = name + b' ' + b' '.join(checked_keys) + b'\r\n'

        try:
            if not self.sock:
                self._connect()

            self.sock.sendall(cmd)

            buf = b''
            result = {}
            while True:
                buf, line = _readline(self.sock, buf)
                self._raise_errors(line, name)
                if line == b'END':
                    return result
                elif line.startswith(b'VALUE'):
                    if expect_cas:
                        _, key, flags, size, cas = line.split()
                    else:
                        try:
                            _, key, flags, size = line.split()
                        except Exception as e:
                            raise ValueError("Unable to parse line %s: %s" %
                                             (line, str(e)))

                    buf, value = _readvalue(self.sock, buf, int(size))
                    key = checked_keys[key]

                    if self.deserializer:
                        value = self.deserializer(key, value, int(flags))

                    if expect_cas:
                        result[key] = (value, cas)
                    else:
                        result[key] = value
                elif name == b'stats' and line.startswith(b'STAT'):
                    key_value = line.split()
                    result[key_value[1]] = key_value[2]
                elif name == b'stats' and line.startswith(b'ITEM'):
                    # For 'stats cachedump' commands
                    key_value = line.split()
                    result[key_value[1]] = b' '.join(key_value[2:])
                else:
                    raise MemcacheUnknownError(line[:32])
        except Exception:
            self.close()
            if self.ignore_exc:
                return {}
            raise
コード例 #2
0
    def test_retry_for_exception_fail(self):
        # Test that we do not retry for unapproved exception.
        client = self.make_client(
            [MemcacheUnknownError("Whoops."), b"VALUE key 0 5\r\nvalue\r\nEND\r\n"],
            attempts=2,
            retry_for=tuple([MemcacheClientError]),
        )

        with pytest.raises(MemcacheUnknownError):
            client.get("key")
コード例 #3
0
ファイル: base.py プロジェクト: JianGuoPinterest/pymemcache
    def _fetch_cmd(self, name, keys, expect_cas):
        prefixed_keys = [self.check_key(k) for k in keys]
        remapped_keys = dict(zip(prefixed_keys, keys))

        # It is important for all keys to be listed in their original order.
        cmd = name + b' ' + b' '.join(prefixed_keys) + b'\r\n'

        try:
            if self.sock is None:
                self._connect()

            self.sock.sendall(cmd)

            buf = b''
            result = {}
            while True:
                buf, line = _readline(self.sock, buf)
                self._raise_errors(line, name)
                if line == b'END' or line == b'OK':
                    return result
                elif line.startswith(b'VALUE'):
                    if expect_cas:
                        _, key, flags, size, cas = line.split()
                    else:
                        try:
                            _, key, flags, size = line.split()
                        except Exception as e:
                            raise ValueError("Unable to parse line %s: %s"
                                             % (line, str(e)))

                    buf, value = _readvalue(self.sock, buf, int(size))
                    key = remapped_keys[key]

                    if self.deserializer:
                        value = self.deserializer(key, value, int(flags))

                    if expect_cas:
                        result[key] = (value, cas)
                    else:
                        result[key] = value
                elif name == b'stats' and line.startswith(b'STAT'):
                    key_value = line.split()
                    result[key_value[1]] = key_value[2]
                elif name == b'stats' and line.startswith(b'ITEM'):
                    # For 'stats cachedump' commands
                    key_value = line.split()
                    result[key_value[1]] = b' '.join(key_value[2:])
                else:
                    raise MemcacheUnknownError(line[:32])
        except Exception:
            self.close()
            if self.ignore_exc:
                return {}
            raise
コード例 #4
0
    def _store_cmd(self, name, key, expire, noreply, data, cas=None):
        key = self.check_key(key)
        if not self.sock:
            self._connect()

        if self.serializer:
            data, flags = self.serializer(key, data)
        else:
            flags = 0

        if not isinstance(data, six.binary_type):
            try:
                data = six.text_type(data).encode('ascii')
            except UnicodeEncodeError as e:
                raise MemcacheIllegalInputError(str(e))

        extra = b''
        if cas is not None:
            extra += b' ' + cas
        if noreply:
            extra += b' noreply'

        cmd = (name + b' ' + key + b' ' +
               six.text_type(flags).encode('ascii') + b' ' +
               six.text_type(expire).encode('ascii') + b' ' +
               six.text_type(len(data)).encode('ascii') + extra + b'\r\n' +
               data + b'\r\n')

        try:
            self.sock.sendall(cmd)

            if noreply:
                return True

            buf = b''
            buf, line = _readline(self.sock, buf)
            self._raise_errors(line, name)

            if line in VALID_STORE_RESULTS[name]:
                if line == b'STORED':
                    return True
                if line == b'NOT_STORED':
                    return False
                if line == b'NOT_FOUND':
                    return None
                if line == b'EXISTS':
                    return False
            else:
                raise MemcacheUnknownError(line[:32])
        except Exception:
            self.close()
            raise
コード例 #5
0
    def _fetch_cluster_info_cmd(self, cmd, name):
        if self.sock is None:
            self._connect()
        self.sock.sendall(cmd)

        buf = b''
        result = {}
        number_of_line = 0

        while True:
            buf, line = _readline(self.sock, buf)
            self._raise_errors(line, name)
            if line == b'END':
                if number_of_line != 2:
                    raise MemcacheUnknownError('Wrong response')
                return result
            if number_of_line == 1:
                try:
                    result = self._extract_cluster_info(line)
                except ValueError:
                    raise MemcacheUnknownError('Wrong format: {line}'.format(
                        line=line, ))
            number_of_line += 1
コード例 #6
0
ファイル: base.py プロジェクト: JianGuoPinterest/pymemcache
    def version(self):
        """
        The memcached "version" command.

        Returns:
            A string of the memcached version.
        """
        cmd = b"version\r\n"
        results = self._misc_cmd([cmd], b'version', False)
        before, _, after = results[0].partition(b' ')

        if before != b'VERSION':
            raise MemcacheUnknownError(
                "Received unexpected response: %s" % results[0])
        return after
コード例 #7
0
    def version(self):
        """
        The memcached "version" command.

        Returns:
            A string of the memcached version.
        """
        cmd = b"version\r\n"
        result = self._misc_cmd(cmd, b'version', False)

        if not result.startswith(b'VERSION '):
            raise MemcacheUnknownError("Received unexpected response: %s" %
                                       (result, ))

        return result[8:]
コード例 #8
0
    def test_both_exception_filters(self):
        # Test interacction between both exception filters.
        client = self.make_client([
            MemcacheClientError("Whoops."),
            b'VALUE key 0 5\r\nvalue\r\nEND\r\n',
            MemcacheUnknownError("Whoops."),
            b'VALUE key 0 5\r\nvalue\r\nEND\r\n',
        ],
                                  attempts=2,
                                  retry_for=tuple([MemcacheClientError]),
                                  do_not_retry_for=tuple(
                                      [MemcacheUnknownError]))

        # Check that we succeed where allowed.
        result = client.get("key")
        assert result == b'value'

        # Check that no retries are attempted for the banned exception.
        with pytest.raises(MemcacheUnknownError):
            client.get("key")
コード例 #9
0
ファイル: base.py プロジェクト: vikaskyadav/pymemcache
    def _fetch_cmd(self, name, keys, expect_cas):
        prefixed_keys = [self.check_key(k) for k in keys]
        remapped_keys = dict(zip(prefixed_keys, keys))

        # It is important for all keys to be listed in their original order.
        cmd = name + b' ' + b' '.join(prefixed_keys) + b'\r\n'

        try:
            if self.sock is None:
                self._connect()

            self.sock.sendall(cmd)

            buf = b''
            result = {}
            while True:
                buf, line = _readline(self.sock, buf)
                self._raise_errors(line, name)
                if line == b'END' or line == b'OK':
                    return result
                elif line.startswith(b'VALUE'):
                    key, value, buf = self._extract_value(expect_cas, line, buf,
                                                          remapped_keys,
                                                          prefixed_keys)
                    result[key] = value
                elif name == b'stats' and line.startswith(b'STAT'):
                    key_value = line.split()
                    result[key_value[1]] = key_value[2]
                elif name == b'stats' and line.startswith(b'ITEM'):
                    # For 'stats cachedump' commands
                    key_value = line.split()
                    result[key_value[1]] = b' '.join(key_value[2:])
                else:
                    raise MemcacheUnknownError(line[:32])
        except Exception:
            self.close()
            if self.ignore_exc:
                return {}
            raise
コード例 #10
0
ファイル: base.py プロジェクト: JianGuoPinterest/pymemcache
    def _store_cmd(self, name, values, expire, noreply, flags=None, cas=None):
        cmds = []
        keys = []

        extra = b''
        if cas is not None:
            extra += b' ' + cas
        if noreply:
            extra += b' noreply'
        expire = six.text_type(expire).encode(self.encoding)

        for key, data in six.iteritems(values):
            # must be able to reliably map responses back to the original order
            keys.append(key)

            key = self.check_key(key)
            if self.serializer:
                data, serializer_flags = self.serializer(key, data)
                # Use the serializer's flags when 'flags' haven't been specified
                # If 'flags' is specified, ignore the serializer_flags generated
                #  from serializer, otherwise use serializer_flags.
                if flags is None:
                    flags = serializer_flags
            # If no 'flags' or 'serializer' passed in, default flags to 0
            if flags is None:
                flags = 0

            if not isinstance(data, six.binary_type):
                try:
                    data = six.text_type(data).encode(self.encoding)
                except UnicodeEncodeError as e:
                    raise MemcacheIllegalInputError(
                            "Data values must be binary-safe: %s" % e)

            cmds.append(name + b' ' + key + b' ' +
                        six.text_type(flags).encode(self.encoding) +
                        b' ' + expire +
                        b' ' + six.text_type(len(data)).encode(self.encoding) +
                        extra + b'\r\n' + data + b'\r\n')

        if self.sock is None:
            self._connect()

        try:
            self.sock.sendall(b''.join(cmds))
            if noreply:
                return {k: True for k in keys}

            results = {}
            buf = b''
            for key in keys:
                buf, line = _readline(self.sock, buf)
                self._raise_errors(line, name)

                if line in VALID_STORE_RESULTS[name]:
                    if line == b'STORED':
                        results[key] = True
                    if line == b'NOT_STORED':
                        results[key] = False
                    if line == b'NOT_FOUND':
                        results[key] = None
                    if line == b'EXISTS':
                        results[key] = False
                else:
                    raise MemcacheUnknownError(line[:32])
            return results
        except Exception:
            self.close()
            raise
コード例 #11
0
ファイル: base.py プロジェクト: tuxskar/pymemcache
    def _store_cmd(self, name, values, expire, noreply, flags=None, cas=None):
        cmds = []
        keys = []

        extra = b''
        if cas is not None:
            cas = self._check_cas(cas)
            extra += b' ' + cas
        if noreply:
            extra += b' noreply'
        expire = self._check_integer(expire, "expire")

        for key, data in six.iteritems(values):
            # must be able to reliably map responses back to the original order
            keys.append(key)

            key = self.check_key(key)
            data, data_flags = self.serde.serialize(key, data)

            # If 'flags' was explicitly provided, it overrides the value
            # returned by the serializer.
            if flags is not None:
                data_flags = flags

            if not isinstance(data, six.binary_type):
                try:
                    data = six.text_type(data).encode(self.encoding)
                except UnicodeEncodeError as e:
                    raise MemcacheIllegalInputError(
                        "Data values must be binary-safe: %s" % e)

            cmds.append(name + b' ' + key + b' ' +
                        six.text_type(data_flags).encode(self.encoding) +
                        b' ' + expire + b' ' +
                        six.text_type(len(data)).encode(self.encoding) +
                        extra + b'\r\n' + data + b'\r\n')

        if self.sock is None:
            self._connect()

        try:
            self.sock.sendall(b''.join(cmds))
            if noreply:
                return {k: True for k in keys}

            results = {}
            buf = b''
            for key in keys:
                buf, line = _readline(self.sock, buf)
                self._raise_errors(line, name)

                if line in VALID_STORE_RESULTS[name]:
                    if line == b'STORED':
                        results[key] = True
                    if line == b'NOT_STORED':
                        results[key] = False
                    if line == b'NOT_FOUND':
                        results[key] = None
                    if line == b'EXISTS':
                        results[key] = False
                else:
                    raise MemcacheUnknownError(line[:32])
            return results
        except Exception:
            self.close()
            raise
コード例 #12
0
ファイル: base.py プロジェクト: shayanadc/pikobot
    def _store_cmd(self, name, values, expire, noreply, cas=None):
        cmds = []
        keys = []

        extra = b''
        if cas is not None:
            extra += b' ' + cas
        if noreply:
            extra += b' noreply'
        expire = six.text_type(expire).encode('ascii')

        for key, data in six.iteritems(values):
            # must be able to reliably map responses back to the original order
            keys.append(key)

            key = self.check_key(key)
            if self.serializer:
                data, flags = self.serializer(key, data)
            else:
                flags = 0

            if not isinstance(data, six.binary_type):
                try:
                    data = six.text_type(data).encode('ascii')
                except UnicodeEncodeError as e:
                    raise MemcacheIllegalInputError(str(e))

            cmds.append(name + b' ' + key + b' ' +
                        six.text_type(flags).encode('ascii') + b' ' + expire +
                        b' ' + six.text_type(len(data)).encode('ascii') +
                        extra + b'\r\n' + data + b'\r\n')

        if not self.sock:
            self._connect()

        try:
            self.sock.sendall(b''.join(cmds))
            if noreply:
                return {k: True for k in keys}

            results = {}
            buf = b''
            for key in keys:
                buf, line = _readline(self.sock, buf)
                self._raise_errors(line, name)

                if line in VALID_STORE_RESULTS[name]:
                    if line == b'STORED':
                        results[key] = True
                    if line == b'NOT_STORED':
                        results[key] = False
                    if line == b'NOT_FOUND':
                        results[key] = None
                    if line == b'EXISTS':
                        results[key] = False
                else:
                    raise MemcacheUnknownError(line[:32])
            return results
        except Exception:
            self.close()
            raise