Search code examples
pythonasynchronouseventletgreen-threads

`eventlet.spawn` doesn't work as expected


I'm writing a web UI for data analysis tasks.

Here's the way it's supposed to work:

After a user specifies parameters like dataset and learning rate, I create a new task record, then a executor for this task is started asyncly (The executor may take a long time to run.), and the user is redirected to some other page.

After searching for an async library for python, I started with eventlet, here's what I wrote in a flask view function:

db.save(task)
eventlet.spawn(executor, task)
return redirect("/show_tasks")

With the code above, the executor didn't execute at all.

What may be the problem of my code? Or maybe I should try something else?


Solution

  • You'll need to patch some system libraries in order to make eventlet work. Here is a minimal working example (also as gist):

    #!/usr/bin/env python 
    
    from flask import Flask 
    import time 
    import eventlet 
    
    eventlet.monkey_patch() 
    
    app = Flask(__name__) 
    app.debug = True 
    
    def background(): 
        """ do something in the background """ 
        print('[background] working in the background...') 
        time.sleep(2) 
        print('[background] done.') 
        return 42 
    
    def callback(gt, *args, **kwargs): 
        """ this function is called when results are available """ 
        result = gt.wait() 
        print("[cb] %s" % result) 
    
    @app.route('/') 
    def index(): 
        greenth = eventlet.spawn(background) 
        greenth.link(callback) 
        return "Hello World" 
    
    if __name__ == '__main__': 
        app.run() 
    

    More on that:

    One of the challenges of writing a library like Eventlet is that the built-in networking libraries don’t natively support the sort of cooperative yielding that we need.