私は数分間動作するWhileループ(関数)を持っています。時には10分、時には30分かかることがあります。
Web ページ ウィンドウを開いたままユーザーを 30 分間待たせたくありません。ユーザーがウィンドウを閉じて、ループを自動的に継続させたいのです。
ユーザーがWebページを開いてボタンをクリックして機能を開始し、ページを閉じて機能を自動的に機能させたい.
そのようなことが可能になる可能性はありますか?
私は数分間動作するWhileループ(関数)を持っています。時には10分、時には30分かかることがあります。
Web ページ ウィンドウを開いたままユーザーを 30 分間待たせたくありません。ユーザーがウィンドウを閉じて、ループを自動的に継続させたいのです。
ユーザーがWebページを開いてボタンをクリックして機能を開始し、ページを閉じて機能を自動的に機能させたい.
そのようなことが可能になる可能性はありますか?
チェックアウトできfastcgi_finish_request()
ます。スクリプトを実行し続けることができますが、ブラウザとの接続を「切断」します。もちろん、慎重に使用する必要があります。そうしないと、セミバックグラウンドで多くのプロセスが実行される危険性があります。
もちろん、これは php-fpm でのみ利用可能です。それ以外の場合はgearman
、基本的にあらゆる種類のタスク スケジューラのようなものを見ていることになります。
スクリプトのタイムアウト (のmax_execution_time
設定php.ini
) が問題にならない場合は、 を使用できますignore_user_abort(true)
。
しかし、通常、そのようなタスクのより良い解決策は、それらをバックグラウンドで生成することです。Gearman拡張機能や のさまざまなバリアントに興味があるかもしれませんexec
。
function execInBackground($cmd) {
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
}
または、db + cron ソリューション。
なぜこのようにフロントエンドでこれほど長いプロセスを実行しているのかを再考する必要があると思います。作業キューを配置して、バックグラウンド デーモンまたはサービス プロセスをできる限り高速に処理してみませんか。
プロセスを開いている人が多すぎて、php が新しいスレッドをスプールできない場合、現在どうなりますか?
エラーが発生した場合、または処理を再試行する必要がある場合はどうなりますか?
私は過去に同様のことをしました。
class Task {
function add($command)
function execute();
}
class TaskManager {
function run(){
$task->execute();
}
}
タスクは、スクリプトまたはシェル コマンドとしてキュー (DB、フラットファイル、石に刻まれたものなど) に追加されます。次に、TaskManager がサービスとして実行され ( http://php.net/manual/en/function.pcntl-fork.phpにいくつかの良いコメントがあります)、キューから最初のアイテムを取得して実行し続けます。
このようにして、長時間実行されるタスクをバックグラウンドで処理でき、多くの不正なプロセスが開始されることはありません。
ユーザーの操作によってスクリプトが停止することはありません。
スクリプトは、終了するかタイムアウト (ほとんどのサーバーでは 15 秒または 30 秒) に達するまで続行されるため、独自のサーバーまたはタイムアウトのないプライベート サーバーがある場合、スクリプトは 30 分間実行され、ユーザーは影響を受けません。 .
注意すべきこと - ユーザーがページを更新したり、時間枠内に再度アクセスした場合に、スクリプトを再度実行させないこと。