Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using gevent.evnet with celery.task

I've been working on a long-polling system. I use flask + mongokit + celery + gevent.

When the process in celery task is done, gevent.event.set() doesn't work. I want help to figure it out. (The reason I use gevent at the same time as celery, is because there is a huge process to deal with in Notification system.)

Here is my sample code.

 #server.py
 @celery.task()
 def doing_task(uid, message):
     notification = Notification() # this is a notification Model
     notification.add(request.args.get('to'), some_notification)
     app.event.set()
     app.event.clear()

 @app.route('/main')
 def main():
     return render_template('main.html')

 @app.route('/set')
 def set():
     doing_task.delay(request.args.get('uid'), 'Notify')
     return 'OK'
 
 @app.route('/poll')
 def poll():
     uid = request.args.get('uid')
     app.event.wait()
     if is_authorized(uid): #uid 1 is a authorized account
         return Notification().get(uid)

 #main.html
 <body>
   <button>Click me</button>
 </body>
 <script>
   $('button').click(function(e) {
    $.ajax({
     'url': '/set',
     'data': 'uid=1',
     'success': function(data) {
       console.log(data);
     }
    });
    e.preventDefault();
  });

      var poll = function() {
  return $.ajax({
           'url': '/poll',
           'method': 'get',
           'async':true,
           'dataType': 'json',
           'timeout': 10000,
           'success': function(data) { 
             console.log(data);
             setTimeout(poll, 50);
           },
           'error':function (req,sta,er){
             setTimeout(poll, 3000);
           }, 
         });
    };
    poll()
 </script>
like image 286
kanghyojmun Avatar asked Oct 08 '22 05:10

kanghyojmun


1 Answers

Now, in Flask 0.9 Flask.app_context is added, With Flask.app_context you can get a context of current.

See Application Context.

For example,

from flask import Flask
from celery import Celery

app = Flask(__name__)
celery = Celery(__name__)

@celery.task
def hello():
    # Also, you are able to deal with current request as use test_request_context 
    with app.app_context():
        print current_app
    with app.test_request_context() as request:
        print('Hello {0!r}'.format(request))
like image 192
kanghyojmun Avatar answered Oct 12 '22 12:10

kanghyojmun