public static function run($callable, $timeout = 0)
{
if (!is_callable($callable)) {
throw new InvalidArgumentException();
}
$timeout = (int) $timeout;
if (!function_exists('pcntl_signal')) {
throw new Exception("PCNTL threading is not supported by your system.");
}
pcntl_signal(SIGALRM, function ($signal) use($timeout) {
throw new TimeoutException("Timeout reached, execution aborted after {$timeout} second(s).");
}, true);
pcntl_alarm($timeout);
$result = null;
try {
$result = $callable();
pcntl_alarm(0);
} catch (Exception $e) {
pcntl_alarm(0);
throw $e;
}
return $result;
}
$start = microtime(true); $closure = function () { Code::run(function () { while (true) { sleep(1); } }, 1); }; expect($closure)->toThrow(new TimeoutException('Timeout reached, execution aborted after 1 second(s).')); $end = microtime(true); expect($end - $start)->toBeGreaterThan(1); }); it("throws all unexpected exceptions", function () { $closure = function () { Code::run(function () { throw new Exception("Error Processing Request"); }, 1); }; expect($closure)->toThrow(new Exception("Error Processing Request")); }); }); } describe("::spin()", function () { it("runs the passed closure", function () { $start = microtime(true); expect(Code::spin(function () { return true; }, 1))->toBe(true); $end = microtime(true); expect($end - $start)->toBeLessThan(1); });