'Mutate a Cassandra key as atomically as possible'

def mutate(self, key, mutation_fn, default=None, willread=True):

    with self.make_lock('permacache_mutate', ('mutate_%s' % key)):
        if willread:
            value = self.cache_chain.get(key, allow_local=False)
            if (value is None):
                value = self._backend_get(key)
        else:
            value = None
        new_value = mutation_fn(copy(value))
        if ((not willread) or (value != new_value)):
            self._backend_set(key, new_value)
        self.cache_chain.set(key, new_value, use_timer=False)
    return new_value
