3

コントローラーからキャッシュをクリアしたい。コマンドをサービスとして定義し、それを呼び出します。

clear_cache_command_service:
    class: Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand
    calls:
       - [setContainer, ["@service_container"] ]

私のコントローラーには、コマンドを選択するためのフォームがあり、キャッシュクリアコマンドが選択されると実行されます。

    $clearCacheCommand = $this->container->get('clear_cache_command_service');
    $clearCacheCommand->run(new ArrayInput(array()), new ConsoleOutput());

ただし、キャッシュもウォームアップするため、これはしばらく実行されます(実際にはキャッシュもウォームアップしたいです)。それもタイムアウトするので、私もそれをする必要がありset_time_limitます。

ブラウザーで応答を返し、サーバーでコマンドを実行して終了させる方法はありますか? クライアントが完了するのを待ち続けたくありません。

4

4 に答える 4

4

同期的に動作するため、phpコマンドが終了して応答を送信するまで待機する必要がある「従来の」方法では実行できません。workerここでの解決策は、パターンを組み込むことです。ここで役立つ情報を見つけることができます。基本的に、「キャッシュのクリア」タスクをキューに追加し、他のプロセスがこのキューを処理できるようにする必要があるため、clear cacheコマンドを呼び出す必要があります。

このような場合に symfony で使用される一般的な解決策は、RabbitMQを使用することです。それに関する多くのリソースがあります:

symfony での使用

RabbitMQバンドル

RabbitMQ に Symfony2 アプリケーションでの作業を任せる

于 2016-02-23T08:26:55.073 に答える
2

応答後にコマンドを実行するには、kernel.terminateイベントでリスナーを使用する必要があります。このイベントの目的は、応答がクライアントに提供された後にタスクを実行することです。

// send the headers and echo the content
$response->send();

// triggers the kernel.terminate event
$kernel->terminate($request, $response);

リスナーの例

kernel.terminate イベントのドキュメント

于 2016-02-23T08:28:36.867 に答える
1

すでに言及されたRabbitMQの代替として、JMSJobBundle http://jmsyst.com/bundles/JMSJobQueueBundle/master/installationを見ることができます

同様の質問に対する私の古い回答で私が与えたいくつかのコード例: Asynchronously calling a Command in Symfony2

于 2016-02-23T13:21:21.230 に答える
0

私はそれを行う方法を見つけました。これにより、すぐに応答が返され、コマンドがバックグラウンドで実行されます。それがどれほど悪い習慣であるかはわかりません。

/**
 * @Service("background_command_runner")
 */
class BackgroundCommandRunner
{
    private $kernelDir;


    /**
     * @InjectParams({
     *     "kernelDir" = @Inject("%kernel.root_dir%")
     * })
     */
    public function __construct($kernelDir)
    {
        $this->kernelDir = $kernelDir;
    }

    public function run($cmd)
    {
        $path = $this->kernelDir . '\console ';

        $fullCmd = "php " . $path . $cmd;

        if (substr(php_uname(), 0, 7) == "Windows") {
            pclose(popen("start /B " . $fullCmd, "r"));
        } else {
            exec($fullCmd . " >> logs/theme.log &");
        }
    }

    public function clearCache($env = "dev", $warm = true)
    {

        $toWarm = $warm ? "" : " --no-warmup";

        $cmd = "cache:clear " . "--env=" . $env . $toWarm;

        $this->run($cmd);

    }


}
于 2016-02-23T08:32:04.947 に答える