Django-Channels:在 class 中锁定临界区
Django-Channels: Lock critical section in class
我有一个 class 扩展 WebsocketConsumer 并因此通过 websocket 与客户端通信。根据我的理解,整个过程是事件驱动的,我有一个方法有一个关键部分(我不想在它仍在处理时再次触发该函数)。
我可以只使用 python 的内置 threading
模块来锁定此部分吗?例如:
import threading
class UserCharacterConsumer(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, *kwargs)
self.lock = threading.Lock()
def critical_method(self):
self.lock.acquire()
try:
# critical section
pass
finally:
self.lock.release()
或者这对 Django-Channels 不起作用,因为它不以那种方式使用线程?
编辑:只为当前用户锁定方法就足够了(甚至只为 class-实例)
这可能在开发中有效,但在生产中会中断,因为您通常有多个进程,甚至可能有多个机器(或 VMs/containers)。
您必须使用一些共享的外部数据存储。你可以为此使用你的数据库,但像 Redis 这样的东西会更可取(例如使用 Redlock)。
可能值得一提的是,这种锁是限制应用程序可伸缩性的瓶颈。我会检查您是否可以使用每用户锁而不是全局锁。
我有一个 class 扩展 WebsocketConsumer 并因此通过 websocket 与客户端通信。根据我的理解,整个过程是事件驱动的,我有一个方法有一个关键部分(我不想在它仍在处理时再次触发该函数)。
我可以只使用 python 的内置 threading
模块来锁定此部分吗?例如:
import threading
class UserCharacterConsumer(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, *kwargs)
self.lock = threading.Lock()
def critical_method(self):
self.lock.acquire()
try:
# critical section
pass
finally:
self.lock.release()
或者这对 Django-Channels 不起作用,因为它不以那种方式使用线程?
编辑:只为当前用户锁定方法就足够了(甚至只为 class-实例)
这可能在开发中有效,但在生产中会中断,因为您通常有多个进程,甚至可能有多个机器(或 VMs/containers)。
您必须使用一些共享的外部数据存储。你可以为此使用你的数据库,但像 Redis 这样的东西会更可取(例如使用 Redlock)。
可能值得一提的是,这种锁是限制应用程序可伸缩性的瓶颈。我会检查您是否可以使用每用户锁而不是全局锁。