基本的に、別のスレッドでサーバー側でイベントを生成しようとしています。私は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.server
app/main/events.py
ファイルにそれが適切なオブジェクトである一方で、何らかの理由でNone
です。私の仕事のように見えるsocketio
オブジェクトは完全に初期化されていない、おそらく、セロリのプロセスの実行フローが異なるので、私はそれを修正する方法がわからない。
クライアントからこのアプリケーションにどのように接続していますか? – Miguel
@Miguel、index.htmlとmagic.js https://gist.github.com/montreal91/8a9ba9033df1469ccd51e1c2e7a3ac9fです。必要に応じて投稿に追加することができます。 'start_countdown'が呼び出されますが、バックグラウンドタスクは開始しません。 – Montreal
メインサーバーに加えて、少なくとも1つのCeleryワーカープロセスを実行していますか? – Miguel