コード例 #1
0
def remove_deal_num_from_lists(deal_sequence_num):
    '''
    Removing deal_sequence_num from any list of deal_sequence_nums that contains
    the specific deal_sequence_num that's passed into this function.

    This is called when a user deletes a deal that he or she has authored.
    '''
    pipe = r.pipeline()
    keys = r.lrange(set_of_deal_list_keys, 0, -1)
    for key in keys:
        nums = pipe.lrange(key, 0, -1)
        if str(deal_sequence_num) in nums:
            pipe.lrem(key, 1, deal_sequence_num)
    pipe.execute()
コード例 #2
0
ファイル: helper.py プロジェクト: chenghanlee/SNG
def remove_deal_num_from_lists(deal_sequence_num):
    '''
    Removing deal_sequence_num from any list of deal_sequence_nums that contains
    the specific deal_sequence_num that's passed into this function.

    This is called when a user deletes a deal that he or she has authored.
    '''
    pipe = r.pipeline()
    keys = r.lrange(set_of_deal_list_keys, 0, -1)
    for key in keys:
        nums = pipe.lrange(key, 0, -1)
        if str(deal_sequence_num) in nums:
            pipe.lrem(key, 1, deal_sequence_num)
    pipe.execute()
コード例 #3
0
def store_list_of_deals(key, deal_seq_nums):
    '''
    Storing a list of deals that correpsonds to a deal query into redis.
    This is used to reduce the need to query mongodb for a list of deals
    that correponds to that query e.g. "get all deals in electronics less
    than 1 wk old and sortd by popularity".

    However, race condition may occur. Therefore, we use pipe.watch and
    pipe.multi to ensure all redis transaction occur atomically. Also, if race
    conditions occur, we will retry up to 25 times. It is ok if we quit after
    25 tries because we will fallback to querying mongohq or whatever datastore
    instead. It will be slower, but we will return the correct result.
    '''
    if len(deal_seq_nums) == 0:
        # storing a -1 to denote that there are no deals associated with this key
        pipe = r.pipeline()
        pipe.rpush(key, 'None')
        pipe.expire(key, cache_timeout)
        pipe.execute()
    else:
        # creating a lock to prevent multiple threads from updating the same
        # key. In other words, we use setnx as a lock to prevent
        # race conditions between threads on updating the same key
        #
        # Also, we set the lock to expire in 10 seconds so if the lock
        # owner dies prior to releasing the lock, the lock will be released
        # automatically by redis
        #
        # Note to self:
        # It is possible that a thread has acquired a lock but the thread
        # dies before assigning an expiration to the lock or releases the lock.
        #
        # If that's the case, use the code below to ensure that we atomically
        # grab the lock and set the lock with an expiration. Because of
        # performance issues and potentially buggy code, the following piece
        # of code is not used
        #
        # lock_obtained = False
        # retries = 10
        # done = False
        # with r.pipeline() as pipe:
        #     while retries > 0 and not done:
        #         try:
        #             retries = retries - 1
        #             pipe.watch('lock')
        #             pipe.multi()
        #             pipe.setnx('lock', obtained)
        #             pipe.expires('lock', 10)
        #             lock_obtained = all(pipe.execute())
        #             done = True
        #         except WatchError
        #             continue

        lock_expiration = 3  # 3 minutes
        if r.setnx('lock', 'obtained'):  # attemp to obtain lock
            r.expire('lock', lock_expiration)
            pipe = r.pipeline()
            for num in deal_seq_nums:
                pipe.rpush(key, num)
            pipe.expire(key, cache_timeout)
            pipe.rpush(set_of_deal_list_keys, key)
            pipe.execute()
            r.delete('lock')  # release lock
コード例 #4
0
ファイル: helper.py プロジェクト: chenghanlee/SNG
def store_list_of_deals(key, deal_seq_nums):
    '''
    Storing a list of deals that correpsonds to a deal query into redis.
    This is used to reduce the need to query mongodb for a list of deals
    that correponds to that query e.g. "get all deals in electronics less
    than 1 wk old and sortd by popularity".

    However, race condition may occur. Therefore, we use pipe.watch and
    pipe.multi to ensure all redis transaction occur atomically. Also, if race
    conditions occur, we will retry up to 25 times. It is ok if we quit after
    25 tries because we will fallback to querying mongohq or whatever datastore
    instead. It will be slower, but we will return the correct result.
    '''
    if len(deal_seq_nums) == 0:
        # storing a -1 to denote that there are no deals associated with this key
        pipe = r.pipeline()
        pipe.rpush(key, 'None')
        pipe.expire(key, cache_timeout)
        pipe.execute()
    else:
        # creating a lock to prevent multiple threads from updating the same
        # key. In other words, we use setnx as a lock to prevent
        # race conditions between threads on updating the same key
        #
        # Also, we set the lock to expire in 10 seconds so if the lock
        # owner dies prior to releasing the lock, the lock will be released
        # automatically by redis
        #
        # Note to self:
        # It is possible that a thread has acquired a lock but the thread
        # dies before assigning an expiration to the lock or releases the lock.
        #
        # If that's the case, use the code below to ensure that we atomically
        # grab the lock and set the lock with an expiration. Because of
        # performance issues and potentially buggy code, the following piece
        # of code is not used
        #
        # lock_obtained = False
        # retries = 10
        # done = False
        # with r.pipeline() as pipe:
        #     while retries > 0 and not done:
        #         try:
        #             retries = retries - 1
        #             pipe.watch('lock')
        #             pipe.multi()
        #             pipe.setnx('lock', obtained)
        #             pipe.expires('lock', 10)
        #             lock_obtained = all(pipe.execute())
        #             done = True
        #         except WatchError
        #             continue

        lock_expiration = 3  # 3 minutes
        if r.setnx('lock', 'obtained'):  # attemp to obtain lock
            r.expire('lock', lock_expiration)
            pipe = r.pipeline()
            for num in deal_seq_nums:
                pipe.rpush(key, num)
            pipe.expire(key, cache_timeout)
            pipe.rpush(set_of_deal_list_keys, key)
            pipe.execute()
            r.delete('lock')  # release lock