Esempio n. 1
0
def coordinated_commit(queued_tasks):
    session = Client().session()
    try:
        session.commit()
    except sqlalchemy.exc.OperationalError as sqlError:
        # If we've sent tasks to redis but have lost the database, those tasks
        # probably point to invalid data. They'll likely fail anyway when the
        # worker can't get the database, and even if they don't, whatever
        # operation they relate to has been lost.

        exc_info = sys.exc_info()
        try:
            for task in queued_tasks:
                task.revoke()
        except (redis.exceptions.ConnectionError,
                redis.exceptions.TimeoutError) as redisError:
            # If we've lost the database, redis connection errors seem likely.
            # Try to report the whole failure.
            raise SkyIsFallingError(sqlError, redisError), None, exc_info[2]

        raise sqlError, None, exc_info[2]
    except (sqlalchemy.exc.DatabaseError,
            sqlalchemy.exc.StatementError) as sqlError:
        exc_info = sys.exc_info()
        try:
            # If we've sent tasks to redis, they probably point to invalid
            # data. Even if they don't, whatever operation they relate to was
            # invalid in some way or another, so this needs to be a
            # coordinated rollback.
            coordinated_rollback(queued_tasks)
            raise sqlError, None, exc_info[2]
        except (redis.exceptions.ConnectionError,
                redis.exceptions.TimeoutError) as redisError:
            raise SkyIsFallingError(sqlError, redisError), None, exc_info[2]
def session_cleanup():
    session = Client().session()
    commit = session.commit
    rollback = session.rollback
    flush = session.flush
    try:
        yield
    finally:
        session.commit = commit
        session.rollback = rollback
        session.flush = flush
    def test_commits_in_the_happy_case(self):
        session = Client().session()
        task = Mock()
        with session_cleanup():
            session.commit = Mock()
            session.rollback = Mock()
            session.rollback.side_effect = \
                    AssertionError("Shouldn't've been called")

            coordinated_commit([task])

            session.commit.assert_called_once_with()
    def test_revokes_tasks_on_connection_error(self):
        session = Client().session()
        task = Mock()
        with session_cleanup():
            session.rollback = Mock()
            session.rollback.side_effect = AssertionError(
                    "Don't try to roll back when the db is unavailable")
            session.commit = Mock()
            session.commit.side_effect = \
                    OperationalError(None, None, 'database timeout')

            assert_raises(OperationalError, lambda: coordinated_commit([task]))

            task.revoke.assert_called_once_with()
    def test_sky_is_falling_if_database_and_redis_are_unreachable(self):
        session = Client().session()
        task = Mock()
        task.revoke.side_effect = TimeoutError('go sit in the corner')
        with session_cleanup():
            session.rollback = Mock()
            session.rollback.side_effect = AssertionError(
                    "Don't try to roll back when the db is unavailable")
            session.commit = Mock()
            session.commit.side_effect = \
                    OperationalError(None, None, b'database timeout')

            assert_raises(SkyIsFallingError,
                          lambda: coordinated_commit([task]))

            task.revoke.assert_called_once_with()
Esempio n. 6
0
session = Client().session()
metadata = MetaData(bind=Client()._engine)

temp_image_tag = Table(
        'temp_image_tags',
        metadata,
        Column('tag_name', String, primary_key=True),
        Column('filename', String, primary_key=True),
        prefixes=['temporary'],
        )
metadata.create_all()

session.execute(temp_image_tag.insert(image_tags))
session.execute(Image.__table__.insert(images))
session.execute(Tag.__table__.insert(tags))

#I can't figure out how to make sqlalchemy generate this query! :(
session.execute("""
insert into image_tag (image_id, tag_id) (
select
    image.image_id,
    tag.tag_id
from
    temp_image_tags
    inner join image using (filename)
    inner join tag on tag.name = temp_image_tags.tag_name
)
        """)

session.commit()