<?php
// Calling it supervisor because it maintains an internal state,
// Receiver because it receives messages.
$supervisor = makeReceiver(); // ...(243) The internal id, optional
// Now we're messaging into that state. Here, we're passing commands.
$supervisor->send(['addUser','amy']);
$supervisor->send(['addUser','bob']);
$supervisor->send(['addUser','ellen']);
$supervisor->send(['addUser','joe']);
$supervisor->send(['addUser','mark']);
$supervisor->send(['addUser','janice']); // Nope
$supervisor->send(['addUser','franke']); // Sorry, too many
// This is a pointer to what's been yielded in the generator.
// It is now an Iterator (next, rewind).
$users = $supervisor->send(_m('iterator'));
function _m($message) {
return [$message, null];
}
foreach($users as $user) {
echo "User is `$user`.".PHP_EOL;
}
// This tells it to hari-kari.
var_dump($supervisor->send(['SIGHUP', $supervisor]));
$supervisor2 = makeReceiver(null, ['eduardo','paul','simon',]);
$supervisor2->send(['addUser','ellen']);
$supervisor2->send(['addUser','joe']);
$users2 = $supervisor2->send(_m('iterator'));
foreach($users2 as $user2) {
echo "User2 is `$user2`.".PHP_EOL;
}
// Walk the plank, aargh! matey!
var_dump($supervisor2->send(['SIGHUP', $supervisor]));
function makeReceiver(?int $id = null, ?array $names = null) {
$names = $names ?? [];
$cNames = 0;
$maxUsers = 5;
$running = true;
$id = $id ?? random_int(1, 500000);
$log = function($signal, $message, ?string $tmpl = null) use($id) {
$tmpl = $tmpl ?? 'Receiver(%d): [%s](%s)';
echo sprintf($tmpl, $id, $signal, \json_encode($message)).PHP_EOL;
};
while ($running) {
list($signal, $message) = yield;
$log($signal, $message);
switch($signal) {
case 'SIGHUP': // Hang up!
$running = false;
return null;
case 'SIGCYC': // Recycle, reset
$names = [];
$cNames = 0;
break;
case 'addUser':
if ($maxUsers > $cNames) {
$names[] = $message;
$cNames++;
}
break;
case 'iterator':
$maxUsers = 0;
yield array_values(array_unique(array_values($names)));
}
}
}
preferences:
37.88 ms | 402 KiB | 5 Q