Skip to content

Instantly share code, notes, and snippets.

@justinyost
Created January 10, 2020 03:01
Show Gist options
  • Save justinyost/0d50327b88d9f7d83955f40e7e281aae to your computer and use it in GitHub Desktop.
Save justinyost/0d50327b88d9f7d83955f40e7e281aae to your computer and use it in GitHub Desktop.
Generators Sample Code
<?php
class Task {
protected $taskId;
protected $coroutine;
protected $sendValue = null;
protected $beforeFirstYield = true;
public function __construct($taskId, Generator $coroutine) {
$this->taskId = $taskId;
$this->coroutine = $coroutine;
}
public function getTaskId() {
return $this->taskId;
}
public function setSendValue($sendValue) {
$this->sendValue = $sendValue;
}
public function run() {
if ($this->beforeFirstYield) {
$this->beforeFirstYield = false;
return $this->coroutine->current();
} else {
$retval = $this->coroutine->send($this->sendValue);
$this->sendValue = null;
return $retval;
}
}
public function isFinished() {
return !$this->coroutine->valid();
}
}
class Scheduler {
protected $maxTaskId = 0;
protected $taskMap = []; // taskId => task
protected $taskQueue;
public function __construct() {
$this->taskQueue = new SplQueue();
}
public function newTask(Generator $coroutine) {
$tid = ++$this->maxTaskId;
$task = new Task($tid, $coroutine);
$this->taskMap[$tid] = $task;
$this->schedule($task);
return $tid;
}
public function schedule(Task $task) {
$this->taskQueue->enqueue($task);
}
public function run() {
while (!$this->taskQueue->isEmpty()) {
$task = $this->taskQueue->dequeue();
echo $task->run();
if ($task->isFinished()) {
unset($this->taskMap[$task->getTaskId()]);
} else {
$this->schedule($task);
}
}
}
}
function task1() {
for ($i = 1; $i <= 10; ++$i) {
echo "This is task 1 iteration $i.\n";
yield;
}
}
function task2() {
for ($i = 1; $i <= 5; ++$i) {
echo "This is task 2 iteration $i.\n";
yield;
}
}
$scheduler = new Scheduler;
$scheduler->newTask(task1());
$scheduler->newTask(task2());
$scheduler->run();
<?php
function getRangeArray($max = 10) {
$array = [];
for ($i = 1; $i < $max; $i++) {
$array[] = $i;
}
return $array;
}
function getRangeGenerator($max = 10) {
for ($i = 1; $i < $max; $i++) {
yield $i;
}
}
class SimpleIterator implements Iterator {
private $position = 1;
private $max = 1;
public function __construct($max = 15) {
$this->position = 1;
$this->max = $max;
}
function rewind() {
$this->position = 1;
}
function current() {
return $this->position;
}
function key() {
return $this->position;
}
function next() {
++$this->position;
}
function valid() {
return ($this->position < $this->max);
}
}
// ---- Toggle each of these in turn. ----
// foreach (getRangeArray(15) as $range) {
// echo "Value: {$range} \n";
// }
// foreach (getRangeArray(PHP_INT_MAX) as $range) {
// echo "Dataset {$range} \n";
// }
// foreach (getRangeGenerator(15) as $range) {
// echo "Dataset {$range} \n";
// }
// foreach ((new SimpleIterator(15)) as $range) {
// echo "Value: {$range} \n";
// }
// foreach ((getRangeGenerator(PHP_INT_MAX)) as $range) {
// echo "Dataset {$range} \n";
// }
foreach ((new SimpleIterator(PHP_INT_MAX)) as $range) {
echo "Value: {$range} \n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment