diff --git a/src/Appwrite/GraphQL/Promises/Adapter/Swoole.php b/src/Appwrite/GraphQL/Promises/Adapter/Swoole.php index 9e04dc10ed..190e7f6873 100644 --- a/src/Appwrite/GraphQL/Promises/Adapter/Swoole.php +++ b/src/Appwrite/GraphQL/Promises/Adapter/Swoole.php @@ -44,26 +44,21 @@ class Swoole extends Adapter return $this->createFulfilled([]); } + // Create the combined promise without an executor (won't start a coroutine) + $combinedPromise = new SwoolePromise(); + // Shared state across callbacks $count = 0; $result = []; $rejected = false; - $resolveCallback = null; - $rejectCallback = null; - $resolveAllWhenFinished = function () use (&$count, $total, &$result, &$rejected, &$resolveCallback): void { - if (!$rejected && $count === $total && $resolveCallback !== null) { + $resolveAllWhenFinished = static function () use (&$count, $total, &$result, &$rejected, $combinedPromise): void { + if (!$rejected && $count === $total) { \ksort($result); - $resolveCallback($result); + $combinedPromise->resolve($result); } }; - // Create the combined promise - the executor captures the resolve/reject callbacks - $combinedPromise = new SwoolePromise(function ($resolve, $reject) use (&$resolveCallback, &$rejectCallback) { - $resolveCallback = $resolve; - $rejectCallback = $reject; - }); - // Register then callbacks on each input promise foreach ($promisesOrValues as $index => $promiseOrValue) { if ($promiseOrValue instanceof GQLPromise) { @@ -74,10 +69,10 @@ class Swoole extends Adapter ++$count; $resolveAllWhenFinished(); }, - static function ($error) use (&$rejected, &$rejectCallback): void { - if (!$rejected && $rejectCallback !== null) { + static function ($error) use (&$rejected, $combinedPromise): void { + if (!$rejected) { $rejected = true; - $rejectCallback($error); + $combinedPromise->reject($error); } } ); diff --git a/src/Appwrite/Promises/Promise.php b/src/Appwrite/Promises/Promise.php index 8de17c13c8..61b8bd8d17 100644 --- a/src/Appwrite/Promises/Promise.php +++ b/src/Appwrite/Promises/Promise.php @@ -201,4 +201,36 @@ abstract class Promise { return $this->result; } + + /** + * Resolve the promise with a value + * + * @param mixed $value + * @return self + */ + public function resolve(mixed $value): self + { + if ($this->state !== self::STATE_PENDING) { + return $this; + } + $this->setResult($value); + $this->setState(self::STATE_FULFILLED); + return $this; + } + + /** + * Reject the promise with a reason + * + * @param mixed $reason + * @return self + */ + public function reject(mixed $reason): self + { + if ($this->state !== self::STATE_PENDING) { + return $this; + } + $this->setResult($reason); + $this->setState(self::STATE_REJECTED); + return $this; + } }