2017-05-12 6 views
0

Symfony/Phpセッションとセッションが既に開いているときに起こるロックについての2つの同様の問題があります。処理に時間がかかります。これは、session_write_close() PHP関数に関連しています。私は、コントローラの先頭にsession_write_close()を使用し、さらに要求をブロックしないためにsymfonyのビルトインサーバではsession_write_close()は動作しません。また、ブラウザには同時にブラウザページがある場合は

<?php 

// TestController.php 

namespace AppBundle\Controller; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 

class TestController extends Controller 
{ 
    /** 
    * @Route("/test", name="test") 
    */ 
    public function testAction(Request $request) 
    { 
     // Close the session to unblock other parallel requests: 
     session_write_close(); 

     $seconds_to_wait = (int) $request->query->get('time', 10); 
     usleep($seconds_to_wait * 1000000); 

     return new Response("Waited for $seconds_to_wait seconds"); 
    } 
} 

:ここ

は、プロセスに時間がかかるコントローラの最小限の一例です。ここで

は、このコントローラにXHRリクエストをテストするために少しのHTML/JSのフロントエンドである:私はprod環境、にこのページをしようとすると、session_write_close()コールへ

<!DOCTYPE html> 
<html> 
    <head><meta charset="UTF-8" /></head> 
    <body> 
     <button>Send requests</button> 
     <ul id="log"></ul> 

     <script type="text/javascript" src="/js/jquery-2.2.4.min.js"></script> 

     <script type="text/javascript"> 

      function log(message) { 
       $('#log').append($('<li>').text(new Date().toTimeString() + ' : ' + message)); 
      } 

      function send_requests() { 
       var times = [ 8, 2, 6 ]; // Send 3 requests, first one is longer than the next one 
       for (var i in times) { 
        log('A request was sent ('+times[i]+'s)'); 
        $.ajax({ 
         url: '/test', data: { time: times[i] }, 
         dataType: 'text', 
         success: function(response) { log(response) } 
        }); 
       } 
      } 

      $(function() { 
       $('button').click(function() { send_requests() }); 
      }); 

     </script> 
    </body> 
</html> 

おかげで、それが使用してせずに正常に動作していますSymfony組み込みのサーバー(代わりにApache)。

14:19:20 GMT+0200 (CEST) : A request was sent (8s) 
14:19:20 GMT+0200 (CEST) : A request was sent (2s) 
14:19:20 GMT+0200 (CEST) : A request was sent (6s) 
14:19:22 GMT+0200 (CEST) : Waited for 2 seconds <-- Right, it didn't wait for the first request 
14:19:26 GMT+0200 (CEST) : Waited for 6 seconds 
14:19:28 GMT+0200 (CEST) : Waited for 8 seconds 

しかし、ここでは二つの問題です:

  • [EDIT:SOLVED]私はdev環境で働いている、symfonyでが構築されたが、例えば、上記のコードは、期待される結果を与えます - サーバでは、それはもはや動作しません。この場合、それはsession_write_close()が呼び出されていないかのように動作し、それ以上の要求は古いものが終了するのを待たなければなりません。ここでは、同じページのための出力が、この異なるコンテキストを持つ:私は代わりのApacheで、いくつかのXHRリクエストをやっているときに私が書いたよう
14:10:06 GMT+0200 (CEST) : A request was sent (8s) 
    14:10:06 GMT+0200 (CEST) : A request was sent (2s) 
    14:10:06 GMT+0200 (CEST) : A request was sent (6s) 
    14:10:14 GMT+0200 (CEST) : Waited for 8 seconds 
    14:10:16 GMT+0200 (CEST) : Waited for 2 seconds <-- Oops, this request had to wait for the 1st one 
    14:10:22 GMT+0200 (CEST) : Waited for 6 seconds 
  • が、それがうまく機能の内蔵サーバ。ブラウザで

    、私は長年の要求(例:/test?time=15)に直接URLを開こう:しかし、そこにはApacheを使用して問題とprod環境もあるが、時で異なるページ同じ時間は、同じ問題が再び起こる:私は2ページ目のために〜30秒を待たなければならない、代わりに15


EDITの:それはのためにです:マティアスは最初の問題のための問題点を指摘しましたアプリケーション開発を支援するために設計されたPHP内蔵サーバーの制限。

答えて

1

DEV /ビルトインサーバーの問題のための単純な答えがあります:

ウェブサーバは、唯一のシングルスレッドプロセスを実行し、その要求がブロックされている場合にPHPアプリケーションが停止します。 (http://php.net/manual/en/features.commandline.webserver.php

ので、この場合の問題は、セッション関連ではなく、Webサーバーは、あなたの要求を同時に処理するサポートしていません。


session_write_close()に関するヒント:あなたは、セッションを保留中のセッションデータを保存して閉じるには、セッションオブジェクトに save()を呼び出すことができます(ご使用のストレージに応じて、 session_write_closeが内部的に呼び出されます)。これは、レスポンスを返す前に、Symfonyが処理の最後に行う処理です( https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/EventListener/SaveSessionListener.php参照)。例:

<?php 

namespace AppBundle\Controller; 

// use ... 

class TestController extends Controller 
{ 
    public function testAction(Request $request) 
    { 
     $request->getSession()->save(); 

     return new Response('foo'); 
    } 
} 
+0

2番目の問題がまだ解決されていない場合でも、Txは答えです。 – yolenoyer

関連する問題