Ejemplo n.º 1
0
def test_read_conflict_rollback_not_reintroduced():
    db = StubDb()
    rollback = StubRollback()

    qa = qube.init({'test': set()})
    qb = qube.init({'test': set()})

    qube.apply_op(qa, ('add', 'test', 'abc', 'tx0'))
    qube.apply_op(qa, ('rem', 'test', 'abc', 'tx456'))

    qube.apply_op(qb, ('add', 'test', 'abc', 'tx0'))
    qube.apply_op(qb, ('rem', 'test', 'abc', 'tx456'))

    qube.rollback(qa, 'tx456')
    qube.apply_op(qa, ('add', 'test', 'def', 'tx789'))

    qube.apply_op(qb, ('add', 'test', 'ghi', 'tx321'))

    def doraise(a, b):
        raise riak.Conflict('the_vclock',
                            'x/zzz',
                            [StubDbResult(qube.to_json(qa)),
                             StubDbResult(qube.to_json(qb))])

    db.get.side_effect = doraise

    m = yield from FooModel.read(db, rollback, 'zzz')

    assert_that(m.qube['journal'], has_length(3))
    assert_that(m.qube['data'], has_entry('test', {'abc', 'def', 'ghi'}))

    assert_that(db.save, called_once_with('foo_bucket',
                                          'zzz',
                                          has_key('data')))
Ejemplo n.º 2
0
Archivo: model.py Proyecto: keis/lera
    def read(cls, db, rollback, key):
        logger.debug("reading %s/%s", cls.bucket, key)

        modified = False
        rollbacks = rollback.txs

        @contextlib.contextmanager
        def queue_rollback(op):
            try:
                yield
            except Exception as e:
                logger.debug('operation failed %r', op)
                cls.queue_rollback(rollback, op)

        try:
            response = yield from db.get(cls.bucket, key)

        except riak.Conflict as e:
            logger.debug("conflict in %s/%s", cls.bucket, key)
            modified = True
            first = e.siblings.pop()

            links = first.links
            vclock = e.vclock
            data = qube.from_json(first)

            for tx in rollbacks:
                qube.rollback(data, tx, error=queue_rollback)

            for r in e.siblings:
                r = qube.from_json(r)

                for tx in rollbacks:
                    qube.rollback(r, tx, error=queue_rollback)

                data = qube.merge(data, r, error=queue_rollback)

        except:
            logger.error("Other error reading", exc_info=True)
            raise

        else:
            links = response.links
            vclock = response.vclock
            data = qube.from_json(response)

            if rollbacks:
                logger.debug("processing rollbacks in %s/%s %r", cls.bucket, key, rollbacks)

                try:
                    seq = data['sequence']
                    for tx in rollbacks:
                        data = qube.rollback(data, tx, error=queue_rollback)
                    modified = seq != data['sequence']
                except:
                    logger.error("error performing rollback", exc_info=True)
                    raise

        model = cls(key, data, vclock=vclock, links=links)

        if modified:
            # Ideally this would happen after returning the list
            # TODO: Task()
            yield from model.save(db)
            yield from rollback.process(db)

        logger.debug('read %s/%s %s', cls.bucket, key, vclock)
        return model