前提・実現したいこと
python(FastAPI)にてServer-Sent Eventsを行おうとしています。
プログラム自体は問題なく動作するのですが、ターミナル上から Control+C で終了しようとすると、
「Waiting for connections to close.」とエラーメッセージが表示され一発で終了することができません。
一度で無事すべてのプロセスを終了させる方法をご教授いただきたいです。
コードの書き方が適切でないため、このメッセージが表示されるのではないかと思っているのですが、
どう直してあげればよいかがわからず、苦戦しております。
発生している問題・エラーメッセージ
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [23908] using watchgod INFO: Started server process [23910] INFO: Waiting for application startup. ︙ INFO: 127.0.0.1:55249 - "GET /static/favicon.ico HTTP/1.1" 200 OK INFO: 127.0.0.1:55249 - "POST /ajax HTTP/1.1" 200 OK ^CINFO: Shutting down INFO: Waiting for connections to close. (CTRL+C to force quit) ^CINFO: Finished server process [23910] INFO: Stopping reloader process [23908]
該当のソースコード
python
1from fastapi import FastAPI, Request, WebSocket 2from fastapi.staticfiles import StaticFiles 3from fastapi.templating import Jinja2Templates 4from fastapi.responses import StreamingResponse 5import random 6import asyncio 7import queue 8 9app = FastAPI() 10app.mount("/static", StaticFiles(directory="static"), name="static") 11templates = Jinja2Templates(directory="templates") 12 13q = asyncio.Queue() 14 15# EventStream 16@app.get('/stream') 17async def message_stream(request: Request): 18 async def event_stream(): 19 while True: 20 event = "test" 21 data = await q.get() 22 yield "event:{}\ndata:{}\n\n".format(event,data) 23 await asyncio.sleep(5) 24 return StreamingResponse(event_stream(), media_type="text/event-stream") 25 26# index 27@app.get("/") 28async def index(request: Request): 29 return templates.TemplateResponse("index.html", {"request": request}) 30 31# ajax 32@app.post("/ajax") 33def ajax(): 34 q.put_nowait("処理①") 35 q.put_nowait("処理②") 36 q.put_nowait("処理③") 37 q.put_nowait("処理④") 38 q.put_nowait("処理⑤") 39 q.put_nowait("処理⑥") 40 q.put_nowait("処理⑦") 41 q.put_nowait("処理⑧") 42 q.put_nowait("処理⑨") 43 q.put_nowait("処理⑩") 44 return "サーバーメッセージ"
javascript
1$(function () { 2 3 var evtSource = new EventSource("/stream"); 4 evtSource.addEventListener("test", function (e) { 5 console.log(e.data); 6 }); 7 8 $("#btn").click(function () { 9 console.log(evtSource); 10 11 $.ajax({ 12 url: "/ajax", 13 type: "POST", 14 }) 15 .done(function (data) { 16 console.log(data); 17 }) 18 .fail(function () { 19 console.log("Error"); 20 }); 21 }); 22}); 23
試したこと・メッセージが発生するパターン
(1)先に開いているブラウザのタブを閉じてから、ターミナル上でControl+Cで閉じると今回のメッセージは発生しません。(タブを開いている状態でターミナルから終了しようとすると、メッセージが発生してしまします。)
(2)エラーメッセージが表示されたあと、Control+C を再度することで強制終了できることは確認済みです。
(3)Ajaxと連携しているボタンをクリックしない状態で、終了しようとした場合も同じメッセージが表示され変化なし。
(4)async関連が悪さをしているのかと睨んで、await asyncio.sleep をコメントアウトしてみたが変化なし。
補足情報(FW/ツールのバージョンなど)
・python3.9
・FastAPI
・Uvicorn
足りない部分がありましたら、再度調べ直し、記載いたしますのでコメント下さい。
何卒、お力添えのほどよろしくお願いいたします。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/01/19 08:45 編集
2021/01/19 09:05