我正在制作一个扭曲的聊天应用程序。假设我的服务器设计的方式是每当它在线检测到客户端时,它就会向客户端发送所有挂起消息(该客户端的那些消息,这些消息在服务器上的python-list中缓存,因为它处于脱机状态)在一个循环中循环,直到列表用尽。像这样:
class MyChat(LineReceiver):
def connectionMade(self):
self.factory.clients.append(self)
while True:
#retrieve first message from a list of pending-messages(queue) of "self"
msg = self.retrieveFromQueue(self)
if msg != "empty":
self.transport.write(msg)
else:
break
def lineReceived(self, line):
...
def connectionLost(self, reason):
...
def retrieveFromQueue(self, who):
msglist = []
if who in self.factory.userMessages:
msglist = self.factory.userMessages[who]
if msglist != []:
msg = msglist.pop(0) #msglist is a list of strings
self.factory.userMessages[self] = msglist
return msg
else:
return "empty"
factory.userMessages = {} #dict of list of incoming messages of users who aren't online
因此,根据我对Twisted的理解,while循环将阻塞主反应器线程,并且任何其他客户端与服务器的任何交互都不会被服务器注册。如果是这种情况,我希望这种方法的替代代码/方法不会阻止扭曲的线程。
更新:由于应用程序的性质,每个用户可能有2000-3000个待处理消息。
答案 0 :(得分:2)
我认为https://glyph.twistedmatrix.com/2011/11/blocking-vs-running.html解决了这一点。
这里的答案取决于self.retrieveFromQueue(self)
究竟是什么。你暗示它是这样的:
if self.list_of_messages:
return self.list_of_messages.pop(0)
return b"empty"
如果是这种情况,那么答案就是一回事。另一方面,如果实现更像是:
return self.remote_mq_client.retrieve_queue_item(self.queue_identifier)
然后答案可能完全是另一回事。但请注意,这是retrieveFromQueue
的实现,答案似乎与此相关。
有一个while
循环并不那么重要。 while
循环反映了这样一个事实(使用Glyph的话),这段代码正在完成工作。
您可能会认为此循环所代表的工作量太大,无法一次完成。如果有数亿个排队的消息,那么将它们逐个复制到连接的发送缓冲区中可能会同时使用大量的时间和内存。在这种情况下,您可能希望考虑生产者/消费者模式和its support in Twisted。这不会使代码更少(或更多)“阻塞”,但它会使它一次运行更短的时间。
所以这里要回答的问题是:
retrieveFromQueue
阻止connectionMade
运行这么久以至于其他客户端注意到服务中断