def test_multi_connection(self): lock_a = Lock("a") lock_b = Lock("b", using='other') with lock_a, lock_b: # Different connections = can hold > 1! assert lock_a.is_held() assert lock_b.is_held()
def test_held_with_prefix(self): if not self.supports_lock_info: self.skipTest( "Only MariaDB 10.0.7+ has the metadata_lock_info plugin on " "which held_with_prefix relies", ) assert Lock.held_with_prefix('') == {} assert Lock.held_with_prefix('mylock') == {} with Lock('mylock-alpha') as lock: assert ( Lock.held_with_prefix('') == {'mylock-alpha': lock.holding_connection_id()} ) assert ( Lock.held_with_prefix('mylock') == {'mylock-alpha': lock.holding_connection_id()} ) assert ( Lock.held_with_prefix('mylock-beta') == {} ) assert Lock.held_with_prefix('') == {} assert Lock.held_with_prefix('mylock') == {}
def test_holding_more_than_one(self): is_mariadb = connection_is_mariadb(connection) supports_multiple_locks = ( is_mariadb and connection.mysql_version >= (10, 0, 2) ) or (not is_mariadb and connection.mysql_version >= (5, 7)) if not supports_multiple_locks: self.skipTest( "Only MySQL 5.7+ and MariaDB 10.0.2+ have the ability to hold " "more than one named lock" ) lock_a = Lock("a") lock_b = Lock("b") with lock_a, lock_b: assert lock_a.is_held()
def test_simple(self): mylock = Lock("mylock") assert not mylock.is_held() with mylock: assert mylock.is_held() assert Lock("mylock").is_held() cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID();") own_connection_id = cursor.fetchone()[0] assert mylock.holding_connection_id() == own_connection_id assert not mylock.is_held() assert not Lock("mylock").is_held()
def test_holding_more_than_one(self): conn = connection supports_multiple_locks = ( (conn.is_mariadb and conn.mysql_version >= (10, 0, 2)) or (not conn.is_mariadb and conn.mysql_version >= (5, 7)) ) if not supports_multiple_locks: self.skipTest( "Only MySQL 5.7+ and MariaDB 10.0.2+ have the ability to hold " "more than one named lock" ) lock_a = Lock("a") lock_b = Lock("b") with lock_a, lock_b: assert lock_a.is_held()
def test_held_with_prefix(self): if not self.supports_lock_info: self.skipTest( "Only MariaDB 10.0.7+ has the metadata_lock_info plugin on " "which held_with_prefix relies" ) assert Lock.held_with_prefix('') == {} assert Lock.held_with_prefix('mylock') == {} with Lock('mylock-alpha') as lock: assert ( Lock.held_with_prefix('') == {'mylock-alpha': lock.holding_connection_id()} ) assert ( Lock.held_with_prefix('mylock') == {'mylock-alpha': lock.holding_connection_id()} ) assert ( Lock.held_with_prefix('mylock-beta') == {} ) assert Lock.held_with_prefix('') == {} assert Lock.held_with_prefix('mylock') == {}
def test_threads_concurrent_access(self): """ Test that the same lock object can be used in multiple threads, allows the definition of a lock upfront in a module. """ if TYPE_CHECKING: # pragma: no branch to_me: queue.Queue[str] to_you: queue.Queue[str] to_me = queue.Queue() to_you = queue.Queue() the_lock = Lock("THElock", 0.05) def check_it_lock_it(): assert not the_lock.is_held() with the_lock: to_me.put("Locked") to_you.get(True) other_thread = Thread(target=check_it_lock_it) other_thread.start() try: item = to_me.get(True) assert item == "Locked" cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID()") own_connection_id = cursor.fetchone()[0] assert the_lock.is_held() assert the_lock.holding_connection_id() != own_connection_id with pytest.raises(TimeoutError): with the_lock: pass to_you.put("Stop") finally: other_thread.join() with the_lock: pass
def test_multi_connection(self): lock_a = Lock("a") lock_b = Lock("b", using="other") with lock_a, lock_b: # Different connections = can hold > 1! assert lock_a.is_held() assert lock_b.is_held()
def test_threads_concurrent_access(self): """ Test that the same lock object can be used in multiple threads, allows the definition of a lock upfront in a module. """ to_me = queue.Queue() to_you = queue.Queue() the_lock = Lock('THElock', 0.05) def check_it_lock_it(): assert not the_lock.is_held() with the_lock: to_me.put("Locked") to_you.get(True) other_thread = Thread(target=check_it_lock_it) other_thread.start() try: item = to_me.get(True) assert item == "Locked" cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID()") own_connection_id = cursor.fetchone()[0] assert the_lock.is_held() assert the_lock.holding_connection_id() != own_connection_id with pytest.raises(TimeoutError): with the_lock: pass to_you.put("Stop") finally: other_thread.join() with the_lock: pass
def test_timeout_with_threads(self): to_me = queue.Queue() to_you = queue.Queue() def lock_until_told(): with Lock('threading_test'): to_me.put("Locked") to_you.get(True) threading_test = Lock('threading_test', 0.05) assert not threading_test.is_held() other_thread = Thread(target=lock_until_told) other_thread.start() try: item = to_me.get(True) assert item == "Locked" cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID();") own_connection_id = cursor.fetchone()[0] assert threading_test.is_held() assert threading_test.holding_connection_id() != own_connection_id with pytest.raises(TimeoutError): with threading_test: pass to_you.put("Stop") finally: other_thread.join() assert not threading_test.is_held() with threading_test: pass
def test_timeout_with_threads(self): if TYPE_CHECKING: # pragma: no cover to_me: queue.Queue[str] to_you: queue.Queue[str] to_me = queue.Queue() to_you = queue.Queue() def lock_until_told(): with Lock("threading_test"): to_me.put("Locked") to_you.get(True) threading_test = Lock("threading_test", 0.05) assert not threading_test.is_held() other_thread = Thread(target=lock_until_told) other_thread.start() try: item = to_me.get(True) assert item == "Locked" cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID();") own_connection_id = cursor.fetchone()[0] assert threading_test.is_held() assert threading_test.holding_connection_id() != own_connection_id with pytest.raises(TimeoutError): with threading_test: pass to_you.put("Stop") finally: other_thread.join() assert not threading_test.is_held() with threading_test: pass
def test_acquire_release(self): my_lock = Lock('not_a_context_manager') my_lock.acquire() my_lock.release()
class LockTests(TestCase): if django.VERSION >= (2, 2): databases = ["default", "other"] else: multi_db = True @classmethod def setUpClass(cls): super().setUpClass() cls.supports_lock_info = connection_is_mariadb( connection ) and connection.mysql_version >= (10, 0, 7) if cls.supports_lock_info: with connection.cursor() as cursor: cursor.execute( """SELECT COUNT(*) FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'metadata_lock_info'""" ) cls.lock_info_preinstalled = cursor.fetchone()[0] > 0 if not cls.lock_info_preinstalled: cursor.execute("INSTALL SONAME 'metadata_lock_info'") @classmethod def tearDownClass(cls): if cls.supports_lock_info and not cls.lock_info_preinstalled: with connection.cursor() as cursor: cursor.execute("UNINSTALL SONAME 'metadata_lock_info'") super().tearDownClass() def test_simple(self): mylock = Lock("mylock") assert not mylock.is_held() with mylock: assert mylock.is_held() assert Lock("mylock").is_held() cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID();") own_connection_id = cursor.fetchone()[0] assert mylock.holding_connection_id() == own_connection_id assert not mylock.is_held() assert not Lock("mylock").is_held() def test_error_on_unneeded_exit(self): mylock = Lock("mylock") assert not mylock.is_held() with pytest.raises(ValueError) as excinfo: mylock.__exit__(None, None, None) assert "unheld lock" in str(excinfo.value) import_time_lock = Lock("defined_at_import_time") def test_defined_at_import_time(self): import_time_lock = self.import_time_lock assert not import_time_lock.is_held() with import_time_lock: assert import_time_lock.is_held() cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID();") own_connection_id = cursor.fetchone()[0] assert import_time_lock.holding_connection_id() == own_connection_id assert not import_time_lock.is_held() def test_timeout_with_threads(self): to_me = queue.Queue() to_you = queue.Queue() def lock_until_told(): with Lock("threading_test"): to_me.put("Locked") to_you.get(True) threading_test = Lock("threading_test", 0.05) assert not threading_test.is_held() other_thread = Thread(target=lock_until_told) other_thread.start() try: item = to_me.get(True) assert item == "Locked" cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID();") own_connection_id = cursor.fetchone()[0] assert threading_test.is_held() assert threading_test.holding_connection_id() != own_connection_id with pytest.raises(TimeoutError): with threading_test: pass to_you.put("Stop") finally: other_thread.join() assert not threading_test.is_held() with threading_test: pass def test_threads_concurrent_access(self): """ Test that the same lock object can be used in multiple threads, allows the definition of a lock upfront in a module. """ to_me = queue.Queue() to_you = queue.Queue() the_lock = Lock("THElock", 0.05) def check_it_lock_it(): assert not the_lock.is_held() with the_lock: to_me.put("Locked") to_you.get(True) other_thread = Thread(target=check_it_lock_it) other_thread.start() try: item = to_me.get(True) assert item == "Locked" cursor = connection.cursor() cursor.execute("SELECT CONNECTION_ID()") own_connection_id = cursor.fetchone()[0] assert the_lock.is_held() assert the_lock.holding_connection_id() != own_connection_id with pytest.raises(TimeoutError): with the_lock: pass to_you.put("Stop") finally: other_thread.join() with the_lock: pass def test_holding_more_than_one(self): is_mariadb = connection_is_mariadb(connection) supports_multiple_locks = ( is_mariadb and connection.mysql_version >= (10, 0, 2) ) or (not is_mariadb and connection.mysql_version >= (5, 7)) if not supports_multiple_locks: self.skipTest( "Only MySQL 5.7+ and MariaDB 10.0.2+ have the ability to hold " "more than one named lock" ) lock_a = Lock("a") lock_b = Lock("b") with lock_a, lock_b: assert lock_a.is_held() def test_multi_connection(self): lock_a = Lock("a") lock_b = Lock("b", using="other") with lock_a, lock_b: # Different connections = can hold > 1! assert lock_a.is_held() assert lock_b.is_held() def test_held_with_prefix(self): if not self.supports_lock_info: self.skipTest( "Only MariaDB 10.0.7+ has the metadata_lock_info plugin on " "which held_with_prefix relies" ) assert Lock.held_with_prefix("") == {} assert Lock.held_with_prefix("mylock") == {} with Lock("mylock-alpha") as lock: assert Lock.held_with_prefix("") == { "mylock-alpha": lock.holding_connection_id() } assert Lock.held_with_prefix("mylock") == { "mylock-alpha": lock.holding_connection_id() } assert Lock.held_with_prefix("mylock-beta") == {} assert Lock.held_with_prefix("") == {} assert Lock.held_with_prefix("mylock") == {} def test_acquire_release(self): my_lock = Lock("not_a_context_manager") my_lock.acquire() my_lock.release()
def test_acquire_release(self): my_lock = Lock("not_a_context_manager") my_lock.acquire() my_lock.release()
def test_holding_more_than_one(self): lock_a = Lock("a") lock_b = Lock("b") with lock_a, lock_b: assert lock_a.is_held()
def handle(self): if self.is_event('CLICK'): activity_id = int(self.input['EventKey'][len(self.view.event_keys['book_header']):]) try: activity = Activity.objects.get(id=activity_id) except Activity.DoesNotExist: raise NotExistError else: try: activity_name = self.get_first_param_in_command() except: return self.reply_text((self.get_message('book_format_wrong'))) activity = Activity.objects.get(name=activity_name) # user if self.user.student_id == "": # 未绑定学号 return self.reply_text(self.get_message('student_id_not_bind')) # activity if not activity: # 活动不存在或活动名输入错误 return self.reply_text(self.get_message('activity_not_exist')) if time.time() < activity.book_start.timestamp(): # 还未到抢票开始时间 return self.reply_text(self.get_message('book_not_start')) if time.time() > activity.book_end.timestamp(): # 已经超过了抢票开始时间 return self.reply_text(self.get_message('book_already_finish')) if activity.remain_tickets <= 0: # 票已抢光 return self.reply_text(self.get_message('tickets_out')) # ticket if Ticket.objects.filter(Q(student_id=self.user.student_id) & Q(activity=activity)).exists(): # 本学号已经抢过票 ticket=Ticket.objects.get(Q(student_id=self.user.student_id) & Q(activity=activity)) if ticket.status==Ticket.STATUS_VALID: return self.reply_text(self.get_message('already_book_tickets')) else: ticket.status=Ticket.STATUS_VALID activity.remain_tickets = activity.remain_tickets - 1 ticket.save() activity.save() return self.reply_text(self.get_message('book_success')) try: with Lock('book_ticket_lock', acquire_timeout=2.0): activity.remain_tickets = activity.remain_tickets - 1 activity.save() except TimeoutError: return self.reply_text('抢票冲突,请稍后再试。') uniqueid=uuid.uuid3(uuid.NAMESPACE_DNS, self.user.student_id).hex+uuid.uuid3(uuid.NAMESPACE_DNS, activity.name).hex try: Ticket.objects.create(student_id=self.user.student_id, unique_id=uniqueid, activity=activity, status=Ticket.STATUS_VALID) except: raise BookFailedError("Book ticket handler error: ticket creation failed") return self.reply_text(self.get_message('book_success'))
def test_error_on_unneeded_exit(self): mylock = Lock("mylock") assert not mylock.is_held() with pytest.raises(ValueError) as excinfo: mylock.__exit__(None, None, None) assert "unheld lock" in str(excinfo.value)
def lock_until_told(): with Lock("threading_test"): to_me.put("Locked") to_you.get(True)
def serialized_func(*args, **kws): with Lock(str(id(func))): return func(*args, **kws)