Page MenuHomePhabricator

D21034.id.diff
No OneTemporary

D21034.id.diff

diff --git a/src/future/Future.php b/src/future/Future.php
--- a/src/future/Future.php
+++ b/src/future/Future.php
@@ -7,7 +7,9 @@
*/
abstract class Future extends Phobject {
- protected $result;
+ private $hasResult = false;
+ private $result;
+
protected $exception;
/**
@@ -79,22 +81,6 @@
}
- /**
- * Retrieve the final result of the future. This method will be called after
- * the future is ready (as per @{method:isReady}) but before results are
- * passed back to the caller. The major use of this function is that you can
- * override it in subclasses to do postprocessing or error checking, which is
- * particularly useful if building application-specific futures on top of
- * primitive transport futures (like @{class:CurlFuture} and
- * @{class:ExecFuture}) which can make it tricky to hook this logic into the
- * main pipeline.
- *
- * @return mixed Final resolution of this future.
- */
- protected function getResult() {
- return $this->result;
- }
-
/**
* Default amount of time to wait on stream select for this future. Normally
* 1 second is fine, but if the future has a timeout sooner than that it
@@ -109,4 +95,38 @@
return $this;
}
+ /**
+ * Retrieve the final result of the future.
+ *
+ * @return wild Final resolution of this future.
+ */
+ final protected function getResult() {
+ if (!$this->hasResult()) {
+ throw new Exception(
+ pht(
+ 'Future has not yet resolved. Resolve futures before retrieving '.
+ 'results.'));
+ }
+
+ return $this->result;
+ }
+
+ final protected function setResult($result) {
+ if ($this->hasResult()) {
+ throw new Exception(
+ pht(
+ 'Future has already resolved. Futures may not resolve more than '.
+ 'once.'));
+ }
+
+ $this->hasResult = true;
+ $this->result = $result;
+
+ return $this;
+ }
+
+ final protected function hasResult() {
+ return $this->hasResult;
+ }
+
}
diff --git a/src/future/FutureProxy.php b/src/future/FutureProxy.php
--- a/src/future/FutureProxy.php
+++ b/src/future/FutureProxy.php
@@ -31,7 +31,9 @@
}
public function resolve() {
- $this->getProxiedFuture()->resolve();
+ $result = $this->getProxiedFuture()->resolve();
+ $result = $this->didReceiveResult($result);
+ $this->setResult($result);
return $this->getResult();
}
@@ -52,15 +54,6 @@
return $this->getProxiedFuture()->getWriteSockets();
}
- protected function getResult() {
- if ($this->result === null) {
- $result = $this->getProxiedFuture()->resolve();
- $result = $this->didReceiveResult($result);
- $this->result = $result;
- }
- return $this->result;
- }
-
public function start() {
$this->getProxiedFuture()->start();
return $this;
diff --git a/src/future/ImmediateFuture.php b/src/future/ImmediateFuture.php
--- a/src/future/ImmediateFuture.php
+++ b/src/future/ImmediateFuture.php
@@ -7,7 +7,7 @@
final class ImmediateFuture extends Future {
public function __construct($result) {
- $this->result = $result;
+ $this->setResult($result);
}
public function isReady() {
diff --git a/src/future/exec/ExecFuture.php b/src/future/exec/ExecFuture.php
--- a/src/future/exec/ExecFuture.php
+++ b/src/future/exec/ExecFuture.php
@@ -381,22 +381,25 @@
* @task resolve
*/
public function resolveKill() {
- if (!$this->result) {
+ if (!$this->hasResult()) {
$signal = 9;
if ($this->proc) {
proc_terminate($this->proc, $signal);
}
- $this->result = array(
+ $result = array(
128 + $signal,
$this->stdout,
$this->stderr,
);
+
+ $this->setResult($result);
+
$this->closeProcess();
}
- return $this->result;
+ return $this->getResult();
}
@@ -764,11 +767,14 @@
}
}
- $this->result = array(
+ $result = array(
$err,
$this->stdout,
$this->stderr,
);
+
+ $this->setResult($result);
+
$this->closeProcess();
return true;
}
@@ -839,11 +845,18 @@
unset($this->windowsStderrTempFile);
if ($this->profilerCallID !== null) {
+ if ($this->hasResult()) {
+ $result = $this->getResult();
+ $err = idx($result, 0);
+ } else {
+ $err = null;
+ }
+
$profiler = PhutilServiceProfiler::getInstance();
$profiler->endServiceCall(
$this->profilerCallID,
array(
- 'err' => $this->result ? idx($this->result, 0) : null,
+ 'err' => $err,
));
$this->profilerCallID = null;
}
diff --git a/src/future/exec/PhutilExecPassthru.php b/src/future/exec/PhutilExecPassthru.php
--- a/src/future/exec/PhutilExecPassthru.php
+++ b/src/future/exec/PhutilExecPassthru.php
@@ -20,8 +20,6 @@
*/
final class PhutilExecPassthru extends PhutilExecutableFuture {
- private $passthruResult;
-
/* -( Executing Passthru Commands )---------------------------------------- */
@@ -105,15 +103,12 @@
// full control of the console. We're just implementing the interfaces to
// make it easier to share code with ExecFuture.
- if ($this->passthruResult === null) {
- $this->passthruResult = $this->execute();
+ if (!$this->hasResult()) {
+ $result = $this->execute();
+ $this->setResult($result);
}
return true;
}
- protected function getResult() {
- return $this->passthruResult;
- }
-
}
diff --git a/src/future/http/HTTPFuture.php b/src/future/http/HTTPFuture.php
--- a/src/future/http/HTTPFuture.php
+++ b/src/future/http/HTTPFuture.php
@@ -180,8 +180,9 @@
if (!$socket) {
$this->stateReady = true;
- $this->result = $this->buildErrorResult(
- HTTPFutureTransportResponseStatus::ERROR_CONNECTION_FAILED);
+ $this->setResult(
+ $this->buildErrorResult(
+ HTTPFutureTransportResponseStatus::ERROR_CONNECTION_FAILED));
return null;
}
@@ -209,16 +210,19 @@
$this->stateReady = true;
if ($timeout) {
- $this->result = $this->buildErrorResult(
- HTTPFutureTransportResponseStatus::ERROR_TIMEOUT);
+ $this->setResult(
+ $this->buildErrorResult(
+ HTTPFutureTransportResponseStatus::ERROR_TIMEOUT));
} else if (!$this->stateConnected) {
- $this->result = $this->buildErrorResult(
- HTTPFutureTransportResponseStatus::ERROR_CONNECTION_REFUSED);
+ $this->setResult(
+ $this->buildErrorResult(
+ HTTPFutureTransportResponseStatus::ERROR_CONNECTION_REFUSED));
} else if (!$this->stateWriteComplete) {
- $this->result = $this->buildErrorResult(
- HTTPFutureTransportResponseStatus::ERROR_CONNECTION_FAILED);
+ $this->setResult(
+ $this->buildErrorResult(
+ HTTPFutureTransportResponseStatus::ERROR_CONNECTION_FAILED));
} else {
- $this->result = $this->parseRawHTTPResponse($this->response);
+ $this->setResult($this->parseRawHTTPResponse($this->response));
}
$profiler = PhutilServiceProfiler::getInstance();
diff --git a/src/future/http/HTTPSFuture.php b/src/future/http/HTTPSFuture.php
--- a/src/future/http/HTTPSFuture.php
+++ b/src/future/http/HTTPSFuture.php
@@ -194,7 +194,7 @@
}
public function isReady() {
- if (isset($this->result)) {
+ if ($this->hasResult()) {
return true;
}
@@ -476,7 +476,7 @@
$body = null;
$headers = array();
- $this->result = array($status, $body, $headers);
+ $this->setResult(array($status, $body, $headers));
} else if ($this->parser) {
$streaming_parser = $this->parser;
try {
@@ -491,12 +491,12 @@
$result = array($ex, null, array());
}
- $this->result = $result;
+ $this->setResult($result);
} else {
// cURL returns headers of all redirects, we strip all but the final one.
$redirects = curl_getinfo($curl, CURLINFO_REDIRECT_COUNT);
$result = preg_replace('/^(.*\r\n\r\n){'.$redirects.'}/sU', '', $result);
- $this->result = $this->parseRawHTTPResponse($result);
+ $this->setResult($this->parseRawHTTPResponse($result));
}
curl_multi_remove_handle(self::$multi, $curl);
@@ -518,7 +518,7 @@
$sink = $this->getProgressSink();
if ($sink) {
- $status = head($this->result);
+ $status = head($this->getResult());
if ($status->isError()) {
$sink->didFailWork();
} else {

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 29, 3:27 AM (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7708531
Default Alt Text
D21034.id.diff (8 KB)

Event Timeline