2

I have two actions, and inside one action I am calling the other one but symfony block on that call until the first one (the one I am calling from) is finished. Therefore due to this fact i am getting time out error. Does anyone know what could be the reason ?

enter image description here

Action is rly simple:

    $url = $this->router->generate(
        'invoice_show',
        [
            'invoiceId' => $invoiceId,
        ],
        UrlGeneratorInterface::ABSOLUTE_URL
    );

    return new Response(
        $this->pdfGenerator->getOutput(
            $url,
            [
                'margin-bottom'       => 3,
                'margin-top'          => 3,
                'margin-left'         => 4,
                'margin-right'        => 4,
                'disable-javascript'  => true,
                'load-error-handling' => 'ignore',
                'cookie'              => $request->cookies->all(),
            ]
        ),
        200,
        [
            'Content-Type'        => 'application/pdf',
            'Content-Disposition' => 'attachment; filename="' . $invoiceId . '.pdf"',
        ]
    );

Exception:

Symfony\Component\Process\Exception\ProcessTimedOutException(code: 0): The process \"/usr/bin/xvfb-run /usr/bin/wkhtmltopdf --lowquality --margin-bottom '3' --margin-left '4' --margin-right '4' --margin-top '3' --disable-javascript --load-error-handling 'ignore' 'http://localhost/invoices/in_1Atlve2rN1gYNyHu4Ixmy8ZI' '/var/www/var/cache/dev/snappy/knp_snappy599cffb13836d0.68608376.pdf'\" exceeded the timeout of 60 seconds. at /var/www/vendor/symfony/symfony/src/Symfony/Component/Process/Process.php:1265

vardius
  • 6,326
  • 8
  • 52
  • 97
  • Nor sure where your posted code is actually calling another controller but I assume things are getting blocked until the complete pdf file is generated? If so, take a look at streamed responses: https://symfony.com/doc/current/components/http_foundation.html#streaming-a-response and https://stackoverflow.com/questions/32839754/how-to-download-stream-large-files-in-symfony2 – Cerad Aug 23 '17 at 02:02
  • `pdfGenerator` calls another action and transforms html to pdf, but the html response never comes. As the application is blocked somehow by the first request where we are w8ing for that pdf file – vardius Aug 23 '17 at 02:56
  • I would suggestion you use the Symfony debug URL to test your application. My article [Reducing KnpPaginatorBundle Database Queries](https://alvinbunk.wordpress.com/2017/05/25/reducing-knppaginatorbundle-database-queries/) shows how to use it and some screenshot (3.2 version). Then you could look in the `var/logs` folder in the `dev.log` specifically, and see if it explains the 504 errors. That's a server error. Also have you looked at KnpSnappyBundle? It's easy to use. @Cerad 's suggestions are good too. – Alvin Bunk Aug 23 '17 at 03:49
  • This is what i am using – vardius Aug 23 '17 at 03:51
  • You should use a debugger and pause the process at some point of execution to see what it is waiting for. See e.g. [xdebug](https://xdebug.org/). – Pieter van den Ham Aug 23 '17 at 04:00
  • You should use @ and my name to respond, because I didn't know you responded till now. What does the dev.log show then? Any useful info? Also maybe the nginx logs might show something. I can't remember where I saw the snappy error logs. Maybe also check logs in the `/var/log` folder. You could be getting wkhtmltopdf errors. – Alvin Bunk Aug 23 '17 at 04:06
  • there is no info about the second request in symfony dev toolbar as it is blocked, basically requesting the html w8 to long and then ngnix kills the process – vardius Aug 23 '17 at 04:15
  • I have updated my question with a log @AlvinBunk – vardius Aug 23 '17 at 04:19
  • And have you setup up proper permissions on wkhtmltopdf as in `755` (others can execute) and does your `var` folder get written to correctly. I can't remember the error I got before, but it might be a permissions issue. – Alvin Bunk Aug 23 '17 at 05:33
  • yes permissions are all right, i event tried to disable ipv6 @AlvinBunk – vardius Aug 23 '17 at 05:34
  • So in `app/config/config.yml` the pdf `binary:` path is set to `/usr/bin/wkhtmltopdf` and that `is` where your wkhtmltopdf is located? Normally it is supposed to be in `/usr/local/bin`, that's where mine is. – Alvin Bunk Aug 23 '17 at 05:38
  • yes this is where it is located, executing command in console does work correctly @AlvinBunk – vardius Aug 23 '17 at 05:40
  • Also check your twig css `href` values; they have to have an absolute path for it to work. As in `/var/www/html/Symfony_project/web/css`. – Alvin Bunk Aug 23 '17 at 05:42
  • i think this would break the `wkhtmltopdf` to execute from console as well am I right ? – vardius Aug 23 '17 at 05:43
  • It can be in either `/usr/local/bin` or /usr/bin` as long as your PATH is set. – Alvin Bunk Aug 23 '17 at 05:57
  • Maybe it's can be recursion, when you called 1 template in other template who calls 1st template =) – Maxim Strutinskiy Aug 23 '17 at 06:21
  • 1
    If it's a completely new request then session blocking might be the issue. What kind of session handler do you use? PdoSessionHandler will block subsequent requests until the session is closed in the first one. – Eugene Aug 23 '17 at 07:46
  • I think that @Eugene is right about session locking. You pass cookies from 1-st request to 2-nd request, so session ids are same. Session locking blocks multiple requests with same sessions. All this requests are processed sequentially. Try to close session before 2-nd request `$request->session->save(); ...2-nd request...; $request->session->start();` – Max P. Aug 23 '17 at 09:07
  • Yes ! it was session id! and xdebug session as well so doing both session save->start and disabling xdebug session was a way to go! You can post ur answer @Eugene – vardius Aug 24 '17 at 00:47

1 Answers1

1

Depending on the session handler which you use with symfony, it might lock the session until the first request is finished. That means all subsequent requests will be blocked to prevent concurrency-issues while writing to the session (writing the same session in two requests might result in losing the first write).

It's the case with PDOSessionHandler, for example.

You can explicitly close the session by calling $request->session->save(); in your controller.

If you don't expect concurrency-issues, e.g. if you don't write to the session at all, you can also disable session locking for the whole application:

session.handler.pdo:
    class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
    public: false
    arguments:
        - "pgsql:host=%database_host%;port=%database_port%;dbname=%database_name%"
        - db_username: %database_user%
          db_password: %database_password%
          db_table: session
          db_id_col: session_id
          db_data_col: session_value
          db_time_col: session_time
          db_lifetime_col: session_lifetime
          lock_mode: 0
Eugene
  • 356
  • 3
  • 14