如何在flask视图函数中并行执行

Nav*_*ava 6 python parallel-processing flask flask-restful

在我python-flask在 port 运行的 Web 应用程序中5001,我有一个场景来创建一个端点,其中所有其他端点视图函数都需要并行执行,然后聚合所有单独的响应以在同一请求生命周期中返回它。

例如, routesflaskapp包含以下view功能

@app.route(/amazon)
def amazon():
   return "amazon"

@app.route(/flipkart)
def flipkart():
   return "flipkart"

@app.route(/snapdeal)
def sd():
   return "snapdeal"
Run Code Online (Sandbox Code Playgroud)

注:在上述三个端点中,network io涉及的金额较大

我正在创建另一个端点,即使在这里也必须集体调用所有其他端点实现。

### This is my endpoint
@app.route(/all)
def do_all():
   # execute all amazon, flipkart, snapdeal implementations
Run Code Online (Sandbox Code Playgroud)

对于上述场景,我建议采用两种方法。

方法 1(多处理方法):

将工作任务编写为单独的函数,通过python-multiprocessing模块调用每个调用者并收集响应

def do_all():
   def worker(name):
      # doing network io task for the given source name
      pass

   for name in ['amazon', 'flipkart', 'snapdeal']:
      p = multiprocessing.Process(target=worker, args=(name,))
      jobs.append(p)
      p.start()

   # Terminating all the process explicitly, Since freezing after execution complete
   for j in jobs:
       j.terminate()

   return 200
Run Code Online (Sandbox Code Playgroud)

在这里,我调用每个子进程,调用工作线程,最后所有子进程都被显式终止,因为wsgi threads我也这么认为。

方法2(请求):

使用python-grequests显式调用每个端点。因此,驻留在同一应用程序中的每个端点将被称为并行,并收集响应

def do_all():
   grequests.post("http://localhost:5001/amazon", data={})
   grequests.post("http://localhost:5001/flipkart", data={})
   grequests.post("http://localhost:5001/snapdeal", data={})
Run Code Online (Sandbox Code Playgroud)

这将通过每个请求生成的每个进程来执行wsgi threads,这里我不知道生成多个进程并且执行后不会终止?

两者可能是相似的,但哪一个可以无缝实施,如果有其他方法可以解决这种情况,请帮助我?为什么?

jaz*_*azz 0

也许你可以使用另一种方法来简化它:

  1. 返回立即响应给用户

    def do_all(): return 'amazon, ... being processed'

  2. 在后台调用所有相关方法。
  3. 让调用的后台方法发送信号

    from blinker import Namespace background = Namespace() amazon_finished = background.signal('amazon-finished') def amazon_bg(): amazon_finished.send(**interesting)

  4. 订阅来自后台工作者的信号。

    def do_all(): amazon_finished.connect(amazon_logic)

  5. 向用户显示后台工作者的返回值。这将是一个新请求(可能在同一路线中)。

    def amazon_logic(sender, **extra): sender

优点是用户可以对每个请求立即响应后台工作人员的状态,错误处理会更容易。

我还没有测试过它,所以你应该自己查找blinker API。