2017-10-10 12 views
0

基本的に、別のスレッドでサーバー側でイベントを生成しようとしています。私はcelery.taskイベントを放出すべきですが、そのコードは決して実行されません。セロリのタスクからイベントを発行する方法

import json 
import time 

from celery import Celery 

from flask import Flask 
from flask import jsonify 
from flask import render_template 
from flask import request 

from flask_socketio import SocketIO 

broker_url = "redis://localhost:6379/1" 

celery = Celery(broker=broker_url) 
app = Flask(__name__) 
socketio = SocketIO(app, message_queue=broker_url) 


@celery.task 
def countdown(n): 
    print("countdown", n) 
    for i in range(n+1): 
     time.sleep(1) 
     socketio.emit(
      "countdown", 
      {"remaining": n - i}, 
      namespace="/test/" 
     ) 


@app.route("/") 
def index(): 
    return render_template("index.html") 


@app.route("/start_countdown/", methods=["POST"]) 
def start_countdown(): 
    data = json.loads(request.data.decode()) 
    countdown.delay([int(data["time"])]) 
    return jsonify(time_to_wait=data["time"]) 


if __name__ == '__main__': 
    socketio.run(debug=True) 

ビューは正常に応答していますが、タスクはサイレントであり、わかりません。なぜですか?

UPD

私はhereのように私のコードを再配置していました。フォルダ構造は完全に同じで、ファイルも同じです。 app/mainフォルダには、tasks.pyファイルがあります。

import time 

from celery import Celery 
from flask_socketio import emit 

from app import socketio 
from config import broker_url 


celery = Celery(broker=broker_url) 

@celery.task 
def countdown(n): 
    print(n) 

    for i in range(n+1): 
     time.sleep(1) 
     print("Socket", socketio) 
     print("Server", socketio.server) 
     socketio.emit(
      "countdown", 
      {"remaining": n - i}, 
      namespace="/test/" 
     ) 

celery -A app.main.tasks workerコマンドでセロリの作業を開始します。 countdownタスクのコードが実行されると、それはこの例外で失敗します。私のタスク内部

[2017-10-12 19:04:07,797: WARNING/ForkPoolWorker-1] 13 
[2017-10-12 19:04:08,799: WARNING/ForkPoolWorker-1] <flask_socketio.SocketIO object at 0x7f07d2a0fc50> 
[2017-10-12 19:04:08,803: ERROR/ForkPoolWorker-1] Task app.main.tasks.countdown[68ae2e43-6ab7-4d52-8b3a-a9aaff46c489] raised unexpected: AttributeError("'NoneType' object has no attribute 'emit'",) 
Traceback (most recent call last): 
    File "/path/to/venv/lib/python3.4/site-packages/celery/app/trace.py", line 374, in trace_task 
    R = retval = fun(*args, **kwargs) 
    File "/path/to/venv/lib/python3.4/site-packages/celery/app/trace.py", line 629, in __protected_call__ 
    return self.run(*args, **kwargs) 
    File "/path/to/tasks.py", line 24, in countdown 
    namespace="/test/" 
    File "/path/to/venv/lib/python3.4/site-packages/flask_socketio/__init__.py", line 357, in emit 
    self.server.emit(event, *args, namespace=namespace, room=room, 
AttributeError: 'NoneType' object has no attribute 'emit' 

socketio.serverapp/main/events.pyファイルにそれが適切なオブジェクトである一方で、何らかの理由でNoneです。私の仕事のように見えるsocketioオブジェクトは完全に初期化されていない、おそらく、セロリのプロセスの実行フローが異なるので、私はそれを修正する方法がわからない。

+0

クライアントからこのアプリケーションにどのように接続していますか? – Miguel

+0

@Miguel、index.htmlとmagic.js https://gist.github.com/montreal91/8a9ba9033df1469ccd51e1c2e7a3ac9fです。必要に応じて投稿に追加することができます。 'start_countdown'が呼び出されますが、バックグラウンドタスクは開始しません。 – Montreal

+0

メインサーバーに加えて、少なくとも1つのCeleryワーカープロセスを実行していますか? – Miguel

答えて

0

セロリタスクは別のtasks.pyモジュールにありますか?例えば:

from tasks import countdown 

とその意志あなたのカウントダウン機能を呼び出す:あなたは、あなたのメインのコードを実行し、追加する必要があります

celery -A tasks worker --loglevel=info 

from celery import Celery 

celery = Celery('tasks', broker=broker_url) 
socketio = SocketIO(app, message_queue=broker_url) 

@celery.task 
def countdown(n): 
    print("countdown", n) 
    for i in range(n+1): 
     time.sleep(1) 
     socketio.emit(
      "countdown", 
      {"remaining": n - i}, 
      namespace="/test/" 
     ) 

その後、プロンプト上で、この作業員を開始することができます別のプロセスで実行する

関連する問題