Burada bir çözüm, değil büyük, ama Linux üzerinde ince çalışacak:
Ayrı bir CLI komut içine işleme PHP bölmek:
- The command line inputs include `$id` and `$item`
- The script writes its PID to a file in `/tmp/$id.$item.pid`
- The script echos results as XML or something that can be read into PHP to stdout
- When finished the script deletes the `/tmp/$id.$item.pid` file
Sizin ana komut (muhtemelen sizin sunucunuza) yapardı:
- `exec("nohup php myprocessing.php $id $item > /tmp/$id.$item.xml");` for each item
- Poll the `/tmp/$id.$item.pid` files until all are deleted (sleep/check poll is enough)
- If they are never deleted kill all the processing scripts and report failure
- If successful read the from `/tmp/$id.$item.xml` for format/output to user
- Delete the XML files if you don't want to cache for later use
Bir arka planlı nohup
başladı uygulaması başlattı komut bağımsız çalışacaktır.
Bu bir POC yazmaya karar verdim yeterince ilgimi.
dnm.php
<?php
$dir = realpath(dirname(__FILE__));
$start = time();
// Time in seconds after which we give up and kill everything
$timeout = 25;
// The unique identifier for the request
$id = uniqid();
// Our "items" which would be supplied by the user
$items = array("foo", "bar", "0xdeadbeef");
// We exec a nohup command that is backgrounded which returns immediately
foreach ($items as $item) {
exec("nohup php proc.php $id $item > $dir/proc.$id.$item.out &");
}
echo "<pre>";
// Run until timeout or all processing has finished
while(time() - $start < $timeout)
{
echo (time() - $start), " seconds\n";
clearstatcache(); // Required since PHP will cache for file_exists
$running = array();
foreach($items as $item)
{
// If the pid file still exists the process is still running
if (file_exists("$dir/proc.$id.$item.pid")) {
$running[] = $item;
}
}
if (empty($running)) break;
echo implode($running, ','), " running\n";
flush();
sleep(1);
}
// Clean up if we timeout out
if (!empty($running)) {
clearstatcache();
foreach ($items as $item) {
// Kill process of anything still running (i.e. that has a pid file)
if(file_exists("$dir/proc.$id.$item.pid")
&& $pid = file_get_contents("$dir/proc.$id.$item.pid")) {
posix_kill($pid, 9);
unlink("$dir/proc.$id.$item.pid");
// Would want to log this in the real world
echo "Failed to process: ", $item, " pid ", $pid, "\n";
}
// delete the useless data
unlink("$dir/proc.$id.$item.out");
}
} else {
echo "Successfully processed all items in ", time() - $start, " seconds.\n";
foreach ($items as $item) {
// Grab the processed data and delete the file
echo(file_get_contents("$dir/proc.$id.$item.out"));
unlink("$dir/proc.$id.$item.out");
}
}
echo "</pre>";
?>
proc.php
<?php
$dir = realpath(dirname(__FILE__));
$id = $argv[1];
$item = $argv[2];
// Write out our pid file
file_put_contents("$dir/proc.$id.$item.pid", posix_getpid());
for($i=0;$i<80;++$i)
{
echo $item,':', $i, "\n";
usleep(250000);
}
// Remove our pid file to say we're done processing
unlink("proc.$id.$item.pid");
?>
Put dnm.php and proc.php in the same folder of your server, load dnm.php and enjoy.
Elbette bu işe almak için nohup (unix) ve PHP cli gerekir.
Çok eğlenceli, daha sonra bunun için bir kullanım bulabilirsiniz.