def test_locks_are_released_when_position0_could_not_be_reached(self):
        connector = FIFORedlock([{'host': 'localhost', 'db': 'mytest'}],
                                fifo_retry_delay=0)

        lock_A = connector.lock('pants', 10000)
        self.assertIsInstance(lock_A, redlock.Lock)
        lock_B = connector.lock('pants', 10000)
        self.assertEqual(lock_B, False)
        connector.unlock(lock_A)

        for server in connector.servers:
            self.assertEqual(server.keys(), [])
示例#2
0
    def test_call_order_orchestrated(
            self,
            critical_section=lambda lock_source, lock: None,
            default_ttl=100):
        connector = FIFORedlock(get_servers_pool(active=1, inactive=0),
                                fifo_queue_length=3,
                                fifo_retry_count=10,
                                fifo_retry_delay=0,
                                retry_delay=.1)

        test_timer = TestTimer()
        shared_memory = []

        def thread_function(name, lock_source):
            lock = lock_source.lock('test_call_order_orchestrated',
                                    ttl=default_ttl)
            self.assertTrue(lock)
            shared_memory.append((name, test_timer.get_elapsed()))
            critical_section(lock_source, lock)

        thread_collection = ThreadCollection()
        thread_collection.start(thread_function, 'Thread A', connector)
        sleep(0.05)
        thread_collection.start(thread_function, 'Thread B', connector)
        sleep(0.051)
        thread_collection.start(thread_function, 'Thread C', connector)
        thread_collection.join()

        actual_order = [entry[0] for entry in shared_memory]
        actual_times = [entry[1] for entry in shared_memory]
        self.assertEquals(['Thread A', 'Thread B', 'Thread C'], actual_order)
        self.assertAlmostEqual(0, actual_times[0], delta=0.03)
        self.assertAlmostEqual(0.15, actual_times[1], delta=0.03)
        self.assertAlmostEqual(0.3, actual_times[2], delta=0.03)
示例#3
0
    def test_locks_are_released_when_position0_could_not_be_reached(self):
        connector = FIFORedlock([{
            'host': 'localhost',
            'db': 'mytest'
        }],
                                fifo_retry_delay=0)

        lock_A = connector.lock('pants', 10000)
        self.assertIsInstance(lock_A, redlock.Lock)
        lock_B = connector.lock('pants', 10000)
        self.assertEqual(lock_B, False)
        connector.unlock(lock_A)

        for server in connector.servers:
            self.assertEqual(server.keys(), [])
示例#4
0
    def test_ephemeral_locks_use_the_ephemeral_ttl_while_regular_locks_have_requested_ttl(
            self):
        """
            pants
            -----
            A       # A locks
            A B     # B locks, now second in queue
            A B C   # C locks, now third in queue
            A B C D # D locks, now fourth in queue. D is retrying much faster than anyone else and with unlimited retries.
            A B C D # After 1 second, the situation is still the same.
            A   C D # B dies unexpectedly, redis removes it due to short TTL
            A C D   # C and D advance one spot
              C D   # A unlocks
            C D     # Within 1 second, C becomes first place
              D     # C unlocks
            D       # Within 1 second, D becomes first place

                    # If D got first place, that means C hasn't correctly secured it's old position while trying to get a new one

        """
        fifo_ephemeral_ttl_ms = 500
        connector = FIFORedlock([{
            'host': 'localhost'
        }],
                                fifo_ephemeral_ttl_ms=fifo_ephemeral_ttl_ms)

        locks = dict()

        # A locks
        locks['A'] = connector.lock('pants', 15000)
        self.assertIsInstance(locks['A'], redlock.Lock)
        for server in connector.servers:
            self.assertAlmostEqual(server.pttl('pants'), 15000, 500)

        # B locks, now second in queue
        def get_lock_b(connector):
            try:
                locks['B'] = connector.lock('pants', 20000)
            except:
                pass

        connector2 = FIFORedlock([{
            'host': 'localhost'
        }],
                                 fifo_ephemeral_ttl_ms=fifo_ephemeral_ttl_ms)

        thread_B = threading.Thread(target=get_lock_b, args=(connector2, ))
        thread_B.start()

        # C locks, now third in queue
        def get_lock_c(connector):
            locks['C'] = connector.lock('pants', 30000)

        thread_C = threading.Thread(target=get_lock_c, args=(connector, ))
        thread_C.start()

        # D locks, now fourth in queue. D is retrying much faster than anyone else.
        def get_lock_d(connector):
            locks['D'] = connector.lock('pants', 25000)

        connector3 = FIFORedlock([{
            'host': 'localhost'
        }],
                                 fifo_retry_delay=0,
                                 fifo_retry_count=2000,
                                 fifo_ephemeral_ttl_ms=1001)

        thread_D = threading.Thread(target=get_lock_d, args=(connector3, ))
        thread_D.start()

        # B dies unexpectedly, redis removes it due to short TTL
        connector2.lock_instance = mock.Mock()
        connector2.lock_instance.side_effect = Exception

        # C and D advance one spot

        # A unlocks
        connector.unlock(locks['A'])

        # Within 2 second, C becomes first place
        sleep(2)
        for server in connector.servers:
            self.assertIn('C', locks)
            self.assertEqual(server.get('pants'), locks['C'].key)

        # C unlocks
        connector.unlock(locks['C'])

        # Within 2 second, D becomes first place
        sleep(2)
        for server in connector.servers:
            self.assertIn('D', locks)
            self.assertEqual(server.get('pants'), locks['D'].key)

        thread_B.join()
        thread_C.join()
        thread_D.join()
示例#5
0
 def setUp(self):
     self.redlock = FIFORedlock(get_servers_pool(active=1, inactive=0))
     self.redlock_with_51_servers_up_49_down = FIFORedlock(
         get_servers_pool(active=51, inactive=49))
     self.redlock_with_50_servers_up_50_down = FIFORedlock(
         get_servers_pool(active=50, inactive=50))
    def test_ephemeral_locks_use_the_ephemeral_ttl_while_regular_locks_have_requested_ttl(self):
        """
            pants
            -----
            A       # A locks
            A B     # B locks, now second in queue
            A B C   # C locks, now third in queue
            A B C D # D locks, now fourth in queue. D is retrying much faster than anyone else and with unlimited retries.
            A B C D # After 1 second, the situation is still the same.
            A   C D # B dies unexpectedly, redis removes it due to short TTL
            A C D   # C and D advance one spot
              C D   # A unlocks
            C D     # Within 1 second, C becomes first place
              D     # C unlocks
            D       # Within 1 second, D becomes first place

                    # If D got first place, that means C hasn't correctly secured it's old position while trying to get a new one

        """
        fifo_ephemeral_ttl_ms = 500
        connector = FIFORedlock([{'host': 'localhost'}],
                                fifo_ephemeral_ttl_ms=fifo_ephemeral_ttl_ms)

        locks = dict()

        # A locks
        locks['A'] = connector.lock('pants', 15000)
        self.assertIsInstance(locks['A'], redlock.Lock)
        for server in connector.servers:
            self.assertAlmostEqual(server.pttl('pants'), 15000, 500)

        # B locks, now second in queue
        def get_lock_b(connector):
            try:
                locks['B'] = connector.lock('pants', 20000)
            except:
                pass
        connector2 = FIFORedlock([{'host': 'localhost'}],
                                 fifo_ephemeral_ttl_ms=fifo_ephemeral_ttl_ms)

        thread_B = threading.Thread(target=get_lock_b, args=(connector2, ))
        thread_B.start()

        # C locks, now third in queue
        def get_lock_c(connector):
            locks['C'] = connector.lock('pants', 30000)
        thread_C = threading.Thread(target=get_lock_c, args=(connector, ))
        thread_C.start()

        # D locks, now fourth in queue. D is retrying much faster than anyone else.
        def get_lock_d(connector):
            locks['D'] = connector.lock('pants', 25000)
        connector3 = FIFORedlock([{'host': 'localhost'}],
                                 fifo_retry_delay=0,
                                 fifo_retry_count=2000,
                                 fifo_ephemeral_ttl_ms=1001)

        thread_D = threading.Thread(target=get_lock_d, args=(connector3, ))
        thread_D.start()


        # B dies unexpectedly, redis removes it due to short TTL
        connector2.lock_instance = mock.Mock()
        connector2.lock_instance.side_effect = Exception

        # C and D advance one spot

        # A unlocks
        connector.unlock(locks['A'])

        # Within 2 second, C becomes first place
        sleep(2)
        for server in connector.servers:
            self.assertIn('C', locks)
            self.assertEqual(server.get('pants'), locks['C'].key)

        # C unlocks
        connector.unlock(locks['C'])

        # Within 2 second, D becomes first place
        sleep(2)
        for server in connector.servers:
            self.assertIn('D', locks)
            self.assertEqual(server.get('pants'), locks['D'].key)

        thread_B.join()
        thread_C.join()
        thread_D.join()