Tornado celery integration hacks

后端 未结 4 1664
逝去的感伤
逝去的感伤 2020-12-08 05:44

Since nobody provided a solution to this post plus the fact that I desperately need a workaround, here is my situation and some abstract solutions/ideas for debate.

4条回答
  •  感动是毒
    2020-12-08 06:13

    Here is our solution to the problem. Since we look for result in several handlers in our application we made the celery lookup a mixin class.

    This also makes code more readable with the tornado.gen pattern.

    from functools import partial
    
    class CeleryResultMixin(object):
        """
        Adds a callback function which could wait for the result asynchronously
        """
        def wait_for_result(self, task, callback):
            if task.ready():
                callback(task.result)
            else:
                # TODO: Is this going to be too demanding on the result backend ?
                # Probably there should be a timeout before each add_callback
                tornado.ioloop.IOLoop.instance().add_callback(
                    partial(self.wait_for_result, task, callback)
                )
    
    
    class ARemoteTaskHandler(CeleryResultMixin, tornado.web.RequestHandler):
        """Execute a task asynchronously over a celery worker.
        Wait for the result without blocking
        When the result is available send it back
        """
        @tornado.web.asynchronous
        @tornado.web.authenticated
        @tornado.gen.engine
        def post(self):
            """Test the provided Magento connection
            """
            task = expensive_task.delay(
                self.get_argument('somearg'),
            )
    
            result = yield tornado.gen.Task(self.wait_for_result, task)
    
            self.write({
                'success': True,
                'result': result.some_value
            })
            self.finish()
    

提交回复
热议问题