【发布时间】:2016-02-12 02:38:23
【问题描述】:
我有一个 Django Web 应用程序,它公开了一个用于控制服务器的 api。在同一台服务器上,我有一个后台进程。 Web 应用程序需要定期通知后台进程发生了一些变化,以便该进程可以从数据库中刷新其信息。现在我已经将它设置为后台进程在启动 Django 应用程序的 wsgi 脚本中的单独线程(使用 multiprocessing.Process)中启动。这对于在开发过程中轻松启动/停止一切非常方便。
我知道有一百种方法可以给这只特殊的猫剥皮,但我正在寻找最优雅的方法。我的直觉是,使用 multiprocessing.Queue 将是一种将数据传递到后台进程的绝妙方法。但是,我不知道队列在 Django 应用程序中的位置。我会在 wsgi 中实例化它吗?如果是这样,我将如何将其传递给应用程序?是否应该在其他地方创建它以便我可以在应用程序视图中访问它?
我很好奇以前是否有人处理过这个挑战。
已解决:
根据 Aviah 的建议,这是我将 SocketServer 与静态类成员 Queue 结合使用的解决方案。效果很好。
我在服务器上的主要启动脚本:
if __name__ == "__main__":
scanner = Scanner(API.queue)
scanner.launch()
print("Launcing Socket Server...")
server = socketserver.TCPServer(('localhost', settings.PORT), API)
server.serve_forever()
API 类:
class API(socketserver.BaseRequestHandler):
queue = Queue()
def handle(self):
data = pickle.loads(self.request.recv(RECEIVE_BUFFER_SIZE))
... bla bla ...
API.queue.put(settings.SIGNALS.update)
response = {Comm.response_label: Comm.response.ok}
self.request.sendall(pickle.dumps(response))
扫描器类:
class Scanner:
def __init__(self, signal_queue):
self.queue = signal_queue
def launch(self):
# Launch the worker thread
x = Process(target=self.scan)
x.start()
def scan(self):
print("FileScanner started...")
# Service Loop
while True:
try:
signal = self.queue.get(block=False)
print("Signal received.")
except queue.Empty:
pass
... bla bla ...
【问题讨论】:
-
你已经看过Celery了吗?
-
我做到了。毫无疑问,它会起作用,但它似乎是一个沉重的解决方案。如果我可以使用队列,那么我可能不需要太多代码,或者添加额外的库等。