class LeaderElection(object): def __init__(self, client, path): self.lock = ZooLock(client, path) def run(self, func, *args, **kwargs): if not callable(func): raise ValueError("leader function is not callable") try: with self.lock: func(*args, **kwargs) except CancelledError: pass def cancel(self): self.lock.cancel()
def test_lock_cancel(self): client1 = get_client_or_skip() client1.connect() event1 = threading.Event() lock1 = ZooLock(client1, self.lockpath, "one") thread1 = threading.Thread(target=self._thread_lock_acquire_til_event, args=("one", lock1, event1)) thread1.start() # wait for this thread to acquire the lock with self.condition: if not self.active_thread: self.condition.wait(5) self.assertEqual(self.active_thread, "one") client2 = get_client_or_skip() client2.connect() event2 = threading.Event() lock2 = ZooLock(client2, self.lockpath, "two") thread2 = threading.Thread(target=self._thread_lock_acquire_til_event, args=("two", lock2, event2)) thread2.start() # this one should block in acquire. check that it is a contender self.assertEqual(lock2.get_contenders(), ["one", "two"]) lock2.cancel() with self.condition: if not "two" in self.cancelled_threads: self.condition.wait() self.assertIn("two", self.cancelled_threads) self.assertEqual(lock2.get_contenders(), ["one"]) thread2.join() event1.set() thread1.join()