Skip to content

Commit

Permalink
Add Condition->trySucceed and Condition->tryFail (#185)
Browse files Browse the repository at this point in the history
Summary:
It would allow for use cases like this:

```
async function outer(): Awaitable<void> {
  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: #185

Reviewed By: fredemmott

Differential Revision: D34903436

Pulled By: Atry

fbshipit-source-id: fbe39b59cccc2dcdbdca0642a5b790dc47e4cf3f
  • Loading branch information
Atry authored and facebook-github-bot committed Mar 21, 2022
1 parent ab659a3 commit c8e0c0a
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions src/async/Condition.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,58 @@ class Condition<T> {
* 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;
}
}

Expand Down

0 comments on commit c8e0c0a

Please sign in to comment.