0

I have an app where I create/generate PDF on data retrieved from client side. When PDF is generated, I send those PDFs to desired emails and create download button, so customer can download that file too. The problem is that sending mails take some 10-15 seconds, maybe even more, before I can create download button. Is there a way I can put that email sending process in background, so I can skip directly to the download part of the code, instead of waiting for mailer to do all the tricks.

$name = md5(time());
$pdfoutput = $in->_config["path"] . '/PDFs/' . $name . '.pdf';
$mpdf->Output( $pdfoutput,'F' );
$subject = "Offer";
$body["html"] = "<b>Offer in html</b>";
$body["text"] = "Offer as text";
$files = array($pdfoutput);
$addresses = array("*******@hotmail.com");

// PROBLEMATIC PART
$mail->createEmails($addresses, $subject, $body, $files); // i want this proces to go in background

$pdfurl = $in->_config["url"] . "PDFs/" . $name . ".pdf";
return json_encode(array("status" => "ok", "reason" => "PDF CREATED!", "pdffile" => $pdfurl));
  • 1
    maybe you should take a look at pcntl_fork: http://php.net/manual/en/function.pcntl-fork.php – steven May 06 '15 at 10:49
  • Consider submitting the emailing task to a job queue rather than trying to run as part of the request – Mark Baker May 06 '15 at 10:51
  • @MarkBaker: You mean like creating queue and then, for instance, use CRON of a system, to check every minute if there are new emails to send? Or how do I execute queues later? –  May 06 '15 at 10:54
  • 1
    There are plenty of serious queueing systems out there to choose from: rabbitmq, zeromq, gearman, etc.... but at the simplest level, writing details to a file/database, and then having a cron task look for that file/database record, read details if it exists, send the emails, then delete the file/database record is a very simple way of creating a background task – Mark Baker May 06 '15 at 10:57
  • Sorry guys, a queueing system is nice, but forking the process should solve the proplem within minutes of implementing. To implement a queueing system should take a lot of more time. – steven May 06 '15 at 11:01
  • Depending on platform, pcntl_fork may not be an option (you can forget it if you're on Windows), even on Linux if you don't have control of your PHP builds..... and a simple cron task is pretty easy to implement as an alternative to either forking or a queueing solution – Mark Baker May 06 '15 at 11:02
  • Well I've tryed pcntl_fork, but with no succes. As I've read, I cannot use it if PHP is installed as apache module :( Here is actual error: [:error] [pid 997] [client 10.4.0.60:35365] PHP Fatal error: Call to undefined function pcntl_fork() in .... –  May 06 '15 at 11:29

2 Answers2

0
PHP Fatal error: Call to undefined function pcntl_fork() 

That just means you have not installed/enabled the pcntl extension. Actually I'd advise against using pcntl from an apache SAPI anyway - you can spawn a PHP instance without pcntl forking from an apache SAPI using shell_exec, and there are some nice wrappers to help with that like cocur.

Queuing via database will work fine, and is very easy if you're already using the DB. Otherwise I recommend beanstalkd and pheanstalk to talk to it. Then run a sending process either from cron or as a daemon.

Synchro
  • 35,538
  • 15
  • 81
  • 104
0

Why don't you move it down and output your json? Flush your buffers too.

http://php.net/manual/en/function.ignore-user-abort.php

MrPHP
  • 152
  • 3
  • 12