Fractaliste
Fractaliste

Reputation: 5957

start /B doesn't start the task

I'm currently launching an asynchronous job with PHP to perform some tests.

To make it work, I found on SO some tips, like the use of popen and start:

$commande = "testu.bat";
$pid = popen('start /B ' . $commande, 'r');
$status = pclose($pid);

The testu.bat's folder is in my user PATH.

This script performs some task, and to control it's execution, it should generates a log file, but I never get it.

Whereas if I just remove the /B option, it works fine and I get my log file.

Did I miss something about background execution? How can I catch the error informations when it is running in the background?

Upvotes: 2

Views: 2114

Answers (6)

E_D
E_D

Reputation: 575

Just for some people seeking this trick to works, in my case it just needs to activate the PHP directive ignore_user_abort in php.ini or by the PHP platform function.

Without this activated, the process is killed by pclose() without finishing the job.

Upvotes: 1

user2609094
user2609094

Reputation:

Your problem is most likely properly solved by using a queue system. You insert a job into a queue that a background process picks up and works on. In this way the background task is completely independent of the HTTP request that initiated the task - but you can still monitor its progress.

The two most popular software packages that can help you in your scenario:

  1. Gearman

  2. RabbitMQ

Note that implementing a queuing solution is not a 5 minute prospect, but it is technically the right approach for this sort of situation. For a company product this is the only viable approach; for a personal project where you just want something to work, there is a level of commitment required to see it through for the first time. If you're looking to expand your development horizons, I strongly suggest you give the queue a shot.

Upvotes: 0

nobody
nobody

Reputation: 20174

It appears you are operating under the assumption that the /B switch to the start command means "background". It does not. From the start usage:

B           Start application without creating a new window. The
            application has ^C handling ignored. Unless the application
            enables ^C processing, ^Break is the only way to interrupt
            the application.

Processes launched by start are asynchronous by default. Since that appears to be what you want, just run the command without the /B switch.

Upvotes: 4

Markus Safar
Markus Safar

Reputation: 6580

In my opinion start launches the specified command by creating a new prcoess in the "background". Therefore the execution of start itself "just" starts the second process and exists immediately. However, using the /B switch, the command to be executed will be excuted in the context of the start process. Therefore the execution of the start process takes longer. Now what I suspect is that executing pclose terminates the start process and as a result of this you don't get your log file.

Maybe one solution (not testet though) could be executing something like start /B cmd "/C testu.bat" where start just tries to execute cmd and cmd gets /C testu.bat as parameter which is the "command" it shall execute.

Another thought: What happens if you don't call $status = pclose($pid);?

Upvotes: 1

Sesertin
Sesertin

Reputation: 462

I'm not quite sure about your goal here, but here are some info you might use:

for figuring out background errors, you may find these functions useful:

set_exception_handler();
set_error_handler();
register_shutdown_function();

Of course write out the errors they catch into some file.

If you do not need any data back from your requests, you can simply use:

fsockopen()
curl

and give them a short timeout (10 milisec). The scripts will run in the backround.

Alternatively if you do need the data back, you can either put it into a database and set up a loop that checks if the data has already been inserted, or simply output it into a file and check for its existence.

Upvotes: 1

malte
malte

Reputation: 1444

Interesting one... Ok, here's what I think is going on: Because you run the task in the background, the PHP script will just carry on, it is not waiting for testu.bat to return anything...

Or put another way, popen does what it was instructed to do, which is starting the task in the background (which it does) but then control is handed immediately back to PHP, whilst the log file is still being created in the background and the php script carries on at the same time...

What I would do in this case is let testu.bat call the php script (or another PHP script) in a callback type fashion once it has done its processing, in a similar way as in Javascript you would use callbacks for asynchromous Ajax calls...

Maybe provide the callback script command as a parameter to testu.bat..?

Hope this is of any help...

Upvotes: 1

Related Questions