Example #1
0
 def test_lock(self, field_name, must_exists=True):
     """
     Test that a lock exists or not on the given field name.
     """
     lock_key = make_key(self.model._name, 'lock-for-update', field_name)
     method = self.test.assertTrue if must_exists else self.test.assertFalse
     method(LimpydBaseTest.database.connection.exists(lock_key))
Example #2
0
 def _unique_key(self, prefix=None):
     """
     Create a unique key.
     """
     prefix_parts = [self.model._name, '__collection__']
     if prefix:
         prefix_parts.append(prefix)
     return unique_key(self.connection, prefix=make_key(*prefix_parts))
Example #3
0
    def _zset_to_keys(self, key, values=None, alpha=False):
        """
        Convert a redis sorted set to a list of keys, to be used by sort.
        Each key is on the following format, for each value in the sorted set:
            ramdom_string:value-in-the-sorted-set => score-of-the-value
        The random string is the same for all keys.
        If values is not None, only these values from the sorted set are saved
        as keys.
        If a value in values is not on the sorted set, it's still saved as a key
        but with a default value ('' is alpha is True, else '-inf')
        """
        conn = self.connection
        default = '' if alpha else '-inf'
        if values is None:
            # no values given, we get scores from the whole sorted set
            result = conn.zrange(key, start=0, end=-1, withscores=True)
            values = list(islice(chain.from_iterable(result), 0, None, 2))
        else:
            # we have values, we'll get only their scores

            if isinstance(self.model.database, PipelineDatabase):
                # if available, use the pipeline of our database to get all
                # scores in one redis call
                with self.model.database.pipeline(transaction=False) as pipe:
                    for value in values:
                        pipe.zscore(key, value)
                    scores = pipe.execute()
            else:
                # no pipeline, we have to do a call for each value
                scores = []
                for value in values:
                    scores.append(conn.zscore(key, value))

            # combine values and scores in one list
            result = []
            for index, value in enumerate(values):
                score = scores[index]
                if score is None:
                    score = default
                result.append((value, score))

        # create a temporary key for each (value,score) tuple
        base_tmp_key = self._unique_key('tmp')
        conn.set(base_tmp_key, 'working...')  # only to "reserve" the main tmp key
        tmp_keys = set()
        # use a mapping dict (tmp_key_with_value=>score) to use in mset
        mapping = {}
        for value, score in result:
            tmp_key = make_key(base_tmp_key, value)
            tmp_keys.add(tmp_key)
            mapping[tmp_key] = score
        # set all keys in one call
        conn.mset(mapping)

        return base_tmp_key, tmp_keys
Example #4
0
 def __init__(self, field, timeout=5, sleep=0.1):
     """
     Save the field and create a real lock,, using the correct connection
     and a computed lock key based on the names of the field and its model.
     """
     self.field = field
     self.sub_lock_mode = False
     super(FieldLock, self).__init__(
         redis=field._model.get_connection(),
         name=make_key(field._model._name, 'lock-for-update', field.name),
         timeout=timeout,
         sleep=sleep,
     )
Example #5
0
 def test_integer_element(self):
     self.assertEqual("integer:key:1", make_key("integer", "key", 1))
Example #6
0
 def test_unicode_element(self):
     self.assertEqual(u"french:key:clé", make_key("french", "key", u"clé"))
Example #7
0
 def test_multi_element_key(self):
     self.assertEqual("complex:key", make_key("complex", "key"))
Example #8
0
 def test_simple_key(self):
     self.assertEqual("simple_key", make_key("simple_key"))
Example #9
0
 def make_key(self, *args):
     """
     Simple shortcut to the make_key global function to create a redis key
     based on all given arguments.
     """
     return make_key(*args)
Example #10
0
 def make_key(cls, *args):
     return make_key(*args)
Example #11
0
 def make_key(self, *args):
     return make_key(*args)