From c8e0c0a1bbe0530685c2de048c7e0661f1c84fab Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Mon, 21 Mar 2022 08:45:09 -0700 Subject: [PATCH 1/2] Add Condition->trySucceed and Condition->tryFail (#185) Summary: It would allow for use cases like this: ``` async function outer(): Awaitable { await wait_for_notification_async( async $notifyee ==> { concurrent { await async { await gen_usleep(100); $notifyee->trySucceed("fast condition"); } await async { await gen_usleep(10000000000); $notifyee->trySucceed("slow condition"); } } } ); } ``` Pull Request resolved: https://github.com/hhvm/hsl/pull/185 Reviewed By: fredemmott Differential Revision: D34903436 Pulled By: Atry fbshipit-source-id: fbe39b59cccc2dcdbdca0642a5b790dc47e4cf3f --- src/async/Condition.php | 44 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/src/async/Condition.php b/src/async/Condition.php index 64acefab..eb277dc3 100644 --- a/src/async/Condition.php +++ b/src/async/Condition.php @@ -21,34 +21,58 @@ class Condition { * Notify the condition variable of success and set the result. */ final public function succeed(T $result): void { + invariant($this->trySucceed($result), 'Unable to notify Condition twice'); + } + + /** + * Notify the condition variable of failure and set the exception. + */ + final public function fail(\Exception $exception): void { + invariant($this->tryFail($exception), 'Unable to notify Condition twice'); + } + + /** + * Notify the condition variable of success and set the $result. + * + * @return + * true if the condition is set to $result successfully, false if the + * condition was previously set to another result or exception. + */ + final public function trySucceed(T $result): bool { if ($this->condition === null) { $this->condition = async { return $result; }; + return true; } else { - invariant( - $this->condition is ConditionWaitHandle<_>, - 'Unable to notify AsyncCondition twice', - ); + if (!($this->condition is ConditionWaitHandle<_>)) { + return false; + } /* HH_FIXME[4110]: Type error revealed by type-safe instanceof feature. See https://fburl.com/instanceof */ $this->condition->succeed($result); + return true; } } /** - * Notify the condition variable of failure and set the exception. + * Notify the condition variable of failure and set the $exception. + * + * @return + * true if the condition is set to $exception successfully, false if the + * condition was previously set to another result or exception. */ - final public function fail(\Exception $exception): void { + final public function tryFail(\Exception $exception): bool { if ($this->condition === null) { $this->condition = async { throw $exception; }; + return true; } else { - invariant( - $this->condition is ConditionWaitHandle<_>, - 'Unable to notify AsyncCondition twice', - ); + if (!($this->condition is ConditionWaitHandle<_>)) { + return false; + } $this->condition->fail($exception); + return true; } } From 7298c866b9e6bb2e1ff8dfc86753236489df9261 Mon Sep 17 00:00:00 2001 From: "Yang, Bo" Date: Mon, 21 Mar 2022 16:06:22 +0000 Subject: [PATCH 2/2] Rename Condition::succeed and Condition::fail to xsucceed and xfail respectively The new name is more consistent with other HSL API --- src/async/Condition.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/async/Condition.php b/src/async/Condition.php index eb277dc3..9b082107 100644 --- a/src/async/Condition.php +++ b/src/async/Condition.php @@ -20,17 +20,33 @@ class Condition { /** * Notify the condition variable of success and set the result. */ - final public function succeed(T $result): void { + final public function xsucceed(T $result): void { invariant($this->trySucceed($result), 'Unable to notify Condition twice'); } /** * Notify the condition variable of failure and set the exception. */ - final public function fail(\Exception $exception): void { + final public function xfail(\Exception $exception): void { invariant($this->tryFail($exception), 'Unable to notify Condition twice'); } + /** + * Notify the condition variable of success and set the result. + */ + <<__Deprecated('use xsucceed() instead')>> + final public function succeed(T $result): void { + $this->xsucceed($result); + } + + /** + * Notify the condition variable of failure and set the exception. + */ + <<__Deprecated('use xfail() instead')>> + final public function fail(\Exception $exception): void { + $this->xfail($exception); + } + /** * Notify the condition variable of success and set the $result. *