質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Bottle

Bottleは、PythonのWebサーバです。1つのPythonファイルで構成されており、非常に軽量。Web APIの作成や導入が簡単で、DjangoやFlaskに比べ使いやすくシンプルなことが特徴です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1889閲覧

Python 3 の Bottle 上で multiprocessing を使ったバックグラウンド処理ができない。

karenDevice

総合スコア28

Bottle

Bottleは、PythonのWebサーバです。1つのPythonファイルで構成されており、非常に軽量。Web APIの作成や導入が簡単で、DjangoやFlaskに比べ使いやすくシンプルなことが特徴です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2021/04/15 07:54

前提・実現したいこと

標題のようにPython3のBottleでバックグラウンド処理がしたいと考えております。
PythonのBottleでbackground taskを処理する を参考にしようとして、記載されているサンプルを自前のサーバー上で動かそうとしたのですが上手く行きません。

発生している問題・エラーメッセージ

前述のサイトの例のように1つ目のブラウザーは /run に、2つ目も /run に、3つ目は / に順にアクセスすると、1つ目の処理が終わってから2つ目の処理が実行され(ここまでは正しい)、2つ目の処理が終わってから3つ目が処理されてしまいます。
とくにエラーメッセージは出ませんでした。

該当のソースコード

使用したコードは以下のとおりで、前述のサイトのサンプルとの変更点は、1行目にshebangを追加したこと、末尾のrunのhostをlocalhostから0.0.0.0にした2点です。

Python3

1#!/usr/bin/env python3 2 3import datetime 4import multiprocessing 5import time 6 7from bottle import Bottle, run 8 9app = Bottle() 10app.process = None 11 12 13def task(): 14 time.sleep(10) 15 16 17def start_task(): 18 if app.process: 19 return False 20 app.process = multiprocessing.Process(target=task) 21 app.process.start() 22 app.process.join() 23 app.process = None 24 return True 25 26 27@app.route('/') 28def index(): 29 dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') 30 return f'index<br>{dt}' 31 32 33@app.route('/run') 34def run_task(): 35 start_dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') 36 response = start_task() 37 end_dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') 38 return f"task complete. <br>Status={response}<br>start={start_dt}<br>end={end_dt}" 39 40 41if __name__ == '__main__': 42 run(app, host='0.0.0.0', port=8001)

試したこと

Bottleなしでmultiprocessingを使ったサンプルを動かしてみましたが、こちらは正しくバックグラウンド処理ができていることを確認しております。

補足情報(FW/ツールのバージョンなど)

自前で用意したサーバーは、Debian(Buster)、Python3のバージョンは3.7.3、Bottleのバージョンは0.12.15です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問の「バックグラウンド処理」にどのような動作を期待しているのかよくわからないので、そこから。

  1. 時間のかかる処理を実施するときに、その処理を別プロセスにまかせてさっさと次の処理ができるようにする。

※ 応答がすぐに返るのでクライアントは待たされないが、処理が終っていないので処理結果はわからない。
2. Webサーバが複数のリクエストを同時に処理できるようにする。
※ 長い時間の処理をするときにはクライアントは待たされる。

1の場合
バックグラウンド処理というと、普通はこっちでしょうね。提示された処理(リンク先のサイト)もこういう動作を実現するための処理のように見えますが、そうなっていません。

python

1 app.process.start() 2 app.process.join()

1行目で別プロセスの処理を起動していますが、2行目で終了を待ち合わせています。 処理が終るまでjoin()は戻らないのでクライアントは10秒またされてしまいます。
また、その間、他のHTTP要求に答えられません。

1のような処理をbottleで実現するにはどうするのが一般的か、ちょっと調べてみたのですがわかりませんでした。
FlaskならCeleryを使ったりします。

2の場合
確認で複数ブラウザを使っているところを見ると、2のように複数の要求を同時に受けらるようにするのが目的のようにも見えます。だとすると、実現方法が異なります。
bottleをマルチスレッド対応にするモジュールpasteを導入するか、gunicornなどのwsgiサーバを導入してそちらのworke経由で動かすかでしょうか。
たとえば10こスレッドを作っておけば、10このリクエストを同時に処理できます。別のブラウザから/runに10個同時にアクセスするとすべてすぐにうけつけられて、すべて10秒後に応答が返るようになります。

投稿2021/04/15 08:40

編集2021/04/15 09:05
TakaiY

総合スコア13790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_obara

2021/04/15 09:02

タイポ gnicorn → gunicorn ですよね。
TakaiY

2021/04/15 09:05

でした。 直しました。
karenDevice

2021/04/15 23:53 編集

バックグラウンド処理ができればご提示の1も2も解決できるものだと勘違いしておりました。 pasteやgunicornのサンプルも見たのですがBottleのシンプルさがなくなる感じでぎりぎり許せる範囲がサイトの例でした。 Bottleのシンプルさが失われてしまうなら自前で用意したサーバーにApacheが入っているのでリクエスト毎にPHPで書く方が早いのかなと思い始めております。 勉強になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問