Beispiel #1
0
    def claim_code(cls, user, deal):
        # check if they already have a code for this deal and return it
        try:
            result = (Session.query(cls).filter(
                and_(cls.user == user._id, cls.deal == deal)).one())
            return result.code
        except NoResultFound:
            pass

        # select an unclaimed code, assign it to the user, and return it
        try:
            claiming = (Session.query(cls).filter(
                and_(cls.deal == deal, cls.user == None,
                     func.pg_try_advisory_lock(cls.id))).limit(1).one())
        except NoResultFound:
            raise GoldPartnerCodesExhaustedError

        claiming.user = user._id
        claiming.date = datetime.now(g.tz)
        Session.add(claiming)
        Session.commit()

        # release the lock
        Session.query(func.pg_advisory_unlock_all()).all()

        return claiming.code
Beispiel #2
0
    def claim_code(cls, user, deal):
        # check if they already have a code for this deal and return it
        try:
            result = (Session.query(cls)
                      .filter(and_(cls.user == user._id,
                                   cls.deal == deal))
                      .one())
            return result.code
        except NoResultFound:
            pass

        # select an unclaimed code, assign it to the user, and return it
        try:
            claiming = (Session.query(cls)
                        .filter(and_(cls.deal == deal,
                                     cls.user == None,
                                     func.pg_try_advisory_lock(cls.id)))
                        .limit(1)
                        .one())
        except NoResultFound:
            raise GoldPartnerCodesExhaustedError

        claiming.user = user._id
        claiming.date = datetime.now(g.tz)
        Session.add(claiming)
        Session.commit()

        # release the lock
        Session.query(func.pg_advisory_unlock_all()).all()

        return claiming.code 
Beispiel #3
0
    def grab_lock(self) -> Generator[Tuple[bool, scoped_session], None, None]:
        """
        Yields a boolean value and a new SQLAlchemy session object.
        The process calling this method should only execute transactions via the session object if the boolean returned is True


        -- Grab lock *
        SELECT pg_try_advisory_lock(23);

        -- Release lock **
        SELECT pg_advisory_unlock(23);

        -- List all advisory locks (all sessions)
        SELECT mode, classid, objid FROM pg_locks WHERE locktype = 'advisory';

        #############################
        #       EXAMPLE USAGE       #
        #############################

        with AdvisoryLock(engine=db.engine, lock_key="6bd4cf27-d68a-4d8a-809c-b07815937052").grab_lock() as locked_session:
            lock, session = locked_session
            if lock:
                # Do stuff with session
                user = session.query(User).filter_by(id=100).first()
                user.hint = "someotherhint"
                session.add(user)
        """
        session = self.session()
        try:
            advisory_lock_key = int(
                hashlib.sha1(self.lock_key.encode("utf-8")).hexdigest(),
                16) % (10**8)

            # *
            advisory_lock = session.execute(
                select([func.pg_try_advisory_lock(advisory_lock_key)
                        ])).fetchone()[0]

            yield (advisory_lock, session)

            # **
            session.execute(
                select([func.pg_advisory_unlock(advisory_lock_key)]))

        except:
            session.rollback()
            raise

        finally:
            session.commit()
            session.close()
Beispiel #4
0
 def run(self):
     
     # Only let one worker run via pg advisory lock
     acquired = Session.execute(select([func.pg_try_advisory_lock(importlockid)])).fetchone()[0]
     threadid = 'PID ' + str(os.getpid()) + ' thread ' + str(threading.current_thread())
     if acquired:
         log.info('[shop worker] %s acquired lock, starting..' % threadid)
     else:
         return
     
     pendingdownloads = False
     while True:
         try:
             downloads = Session.query(ShopDownload) \
                                .filter(ShopDownload.isdone==False) \
                                .filter(ShopDownload.failedimport==False) \
                                .all()
             pendingdownloads = len(downloads) != 0
             if pendingdownloads:
                 rtorrent = xmlrpclib.ServerProxy(Config.SHOP_RPC_URL)
                 for download in downloads:
                     try:
                         infohash = download.infohash
                         iscomplete = rtorrent.d.get_complete(infohash) == 1
                         if iscomplete:
                             shopservice.importDownload(download)
                     except:
                         exc_type, exc_value, exc_traceback = sys.exc_info()
                         importtrace = repr(traceback.format_exception(exc_type, exc_value, exc_traceback))
                         log.error('[shop worker] caught exception in loop ' + importtrace)
                         Session.rollback()
                         Session.begin()
                         download.failedimport = True
                         download.importtrace = importtrace
                         Session.commit()
         except Exception as e:
             log.error('[shop worker] caught exception out of loop ' + repr(e))
             Session.rollback()
         if pendingdownloads:
             time.sleep(10)
         else:
             time.sleep(30)