私は基本的にPythonスクリプトのブラウザインタフェースとして機能するweb2pyアプリケーションを持っています。このスクリプトは通常かなり早く戻りますが、時には時間がかかることがあります。スクリプトの実行が長時間かかると、ユーザーがそのスクリプトの実行を停止する方法を提供したいと考えています。マルチプロセスでweb2pyで長時間実行されるアクションを停止する
は、私は現在、このような関数を呼び出しています:特定のオプションと呼ばれる
def myView(): # this function is called from ajax
session.model = myFunc() # myFunc is from a module which i have complete control over
return dict(model=session.model)
myFunc
は、マルチプロセッシングを使用していますが、まだ長い時間がかかってしまいます。私は、関数を終了するために、または少なくともスレッドの子プロセスを終了させるための何らかの方法が必要です。
私が試した最初のものは、新しいプロセスでmyFunc
を実行し、それを殺すために自分の単純なイベントシステムをロールすることでした:
# in the controller
def myView():
p_conn, c_conn = multiprocessing.Pipe()
events = multiprocessing.Manager().dict()
proc = multiprocessing.Process(target=_fit, args=(options, events c_conn))
proc.start()
sleep(0.01)
session.events = events
proc.join()
session.model = p_conn.recv()
return dict(model=session.model)
def _fit(options, events pipe):
pipe.send(fitting.logistic_fit(options=options, events=events))
pipe.close()
def stop():
try:
session.events['kill']()
except SystemExit:
pass # because it raises that error intentionally
return dict()
# in the module
def kill():
print multiprocessing.active_children()
for p in multiprocessing.active_children():
p.terminate()
raise SystemExit
def myFunc(options, events):
events['kill'] = kill
私はこれでいくつかの主要な問題に遭遇しました。
- は
stop()
でのセッションはとてもsession.events
なしではなかった、myView()
に常にセッションと同じではありませんでした。 - セッションが同じであっても、
kill()
は子を正しく殺していませんでした。 - 長時間実行される関数はweb2pyスレッドをハングするので、関数が終了するまで
stop()
は処理されませんでした。
私はjoin()
を呼び出して、後で関数の結果を拾うためにAJAXを使用していないと考えるが、私は後で使用するためにsession
のプロセスオブジェクトを保存することができませんでした。パイプは節約できると思われましたが、別のビューから同じセッションにアクセスできないという問題がありました。
この機能はどのように実装できますか?
あなたは答えにお答えください。答えに値するいくつかの具体的な事柄:スケジューラーはスクリプトからすぐにタスクを開始しますか?どのようにタスクの結果を得るには?どのように強制的にタスクを停止する?そうであるように、これは完全に質問に答えるものではありません。 – Scimonster
あなたの最後の質問に答える答えを更新しました。あなたの最初の2つの質問は、リンクされたドキュメントに記載されています。それらは一般的なスケジューラー機能を含み、元の質問の一部ではないので、私は答えを更新しませんが、デフォルトでは新しいタスクがすぐにキューに入れられることを簡単に言及します(そして、 'immediate = True')、' scheduler.task_status() 'メソッドを使用して結果を取得します。 – Anthony