Skip to content

Instantly share code, notes, and snippets.

@AMHOL
Created April 5, 2014 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AMHOL/9999508 to your computer and use it in GitHub Desktop.
Save AMHOL/9999508 to your computer and use it in GitHub Desktop.
<?php namespace AMH;
use Exception;
use Jeremeamia\SuperClosure\SerializableClosure;
use Symfony\Component\Process\PhpProcess;
class PromiseValueException extends Exception {}
class Promise
{
protected $_promises = array();
protected $_resolvedPromises = array();
public function __set($key, $callback)
{
if ( !is_callable($callback) ) {
throw new PromiseValueException('You can only set callbacks as promise properties');
}
$functionCode = serialize(new SerializableClosure($callback));
$phpCode =
'<?php
include "../vendor/autoload.php";
$callback = unserialize("'. str_replace('"', '\\"', $functionCode) .'");
echo serialize($callback());
?>';
$promise = new PhpProcess($phpCode);
$promise->start();
$this->_promises[$key] = $promise;
}
public function __get($key)
{
if ( !isset($this->_resolvedPromises[$key]) ) {
$this->_promises[$key]->wait();
$serializedOutput = $this->_promises[$key]->getOutput();
if ( !$this->_isSerialized($serializedOutput) ) {
throw new Exception('Content "'. $serializedOutput .'" returned from Promise could not be unserialized');
}
$this->_resolvedPromises[$key] = unserialize($serializedOutput);
unset($this->_promises[$key]);
}
return $this->_resolvedPromises[$key];
}
public function _isSerialized($str)
{
return ($str == serialize(false) || @unserialize($str) !== false);
}
public function __destruct()
{
try {
foreach($this->_promises as $key => $promise) {
$this->_promises[$key]->stop(0);
}
} catch ( Exception $e ) {}
}
}
@AMHOL
Copy link
Author

AMHOL commented Apr 5, 2014

include '../vendor/autoload.php';
$time_start = microtime(true);
try {
  $Promise = new AMH\Promise;
  $Promise->test = function() {
      return json_decode(file_get_contents('http://echo.jsontest.com/key/value'));
  };
  $Promise->test;
} catch ( Exception $e ) {
  echo $e->getMessage();
}
$time_end = microtime(true);
$time = $time_end - $time_start;

echo "Did nothing in $time seconds\n";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment