Help me understand how exactly Pool::collect works.
Pool::collect — Collect references to completed tasks
public void Pool::collect
Pool::collect
traverses a list of objects passing each one to the $collector
.
The $collector
function should return true
when the engine can destroy the reference to the Threaded
object in the work list.
The ::collect
functionality was moved to Worker
, though it's still exposed by Pool
for utility.
There are two lists, one list of items ready to be executed, and another of items that have been executed (or is currently being executed).
Pool::collect
traverses the second list, items that have been executed (or is currently being executed).
Pool::collect
returns the number of items still left in the garbage list for all Worker
objects in the Pool
to aid with scheduling garbage collection.
<?php
$pool = new Pool(4);
while (@$i++<10) {
$pool->submit(new class($i) extends Threaded {
public function __construct($id) {
$this->id = $id;
}
public function run() {
printf(
"Hello World from %d\n", $this->id);
}
public $id;
});
}
while ($pool->collect(function(Collectable $work){
printf(
"Collecting %d\n", $work->id);
return $work->isGarbage();
})) continue;
$pool->shutdown();
?>
Will yield something like:
Hello World from 1
Hello World from 2
Hello World from 3
Hello World from 4
Hello World from 8
Collecting 1
Hello World from 7
Hello World from 5
Collecting 5
Hello World from 6
Collecting 9
Collecting 2
Collecting 6
Collecting 10
Hello World from 9
Collecting 3
Collecting 7
Collecting 4
Hello World from 10
Collecting 8
Collecting 5
Collecting 10
You missed the audit cycle. Task can not be completed immediately, so at first the collect function do not receive positive result. Several times need to check, it requires a cycle.
In the example if infinite is true, always 4 tasks working. Otherwise, if size of queue is equal with pool size (4), it is over, you can exit the loop.
<?php
class Task extends \Threaded
{
protected $result;
protected $completed = false;
public function run()
{
echo "Task complete\n";
$this->result = md5(rand(1, 2000));
sleep(rand(1, 5));
$this->completed = true;
}
public function isCompleted()
{
return $this->completed;
}
public function getResult()
{
return $this->result;
}
}
$infinite = false;
$poolSize = 4;
$queue = array();
$pool = new \Pool($poolSize);
$pool->submit(new Task);
$pool->submit(new Task);
$pool->submit(new Task);
$pool->submit(new Task);
do {
if($infinite === true){
$queue = array();
}
$pool->collect(function (\Task $task) use (&$queue) {
if ($task->isCompleted()) {
echo "Collect task\n";
$queue[] = $task->getResult();
return true;
} else {
echo "task not complete\n";
return false;
}
});
$size = sizeof($queue);
if ($size > 0) {
echo $size . " result\n";
print_r($queue);
if($infinite === true) {
for ($m = 0; $m < $size; $m++) {
$pool->submit(new Task);
}
} else{
if($size == $poolSize){
break;
}
}
}
usleep(100000);
} while (true);
$pool->shutdown();