Skip to content

Commit 1802903

Browse files
authored
Merge pull request #108 from mcg-web/optimizations
Optimize react promise
2 parents 353bdf3 + cfb1d27 commit 1802903

File tree

4 files changed

+94
-14
lines changed

4 files changed

+94
-14
lines changed

Executor/Promise/Adapter/ReactPromiseAdapter.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,34 +41,43 @@ public function convertThenable($thenable)
4141
/**
4242
* Synchronously wait when promise completes.
4343
*
44-
* @param Promise $promise
44+
* @param Promise $promise
45+
* @param callable $onProgress
4546
*
4647
* @return ExecutionResult
4748
*
4849
* @throws \Exception
4950
*/
50-
public function wait(Promise $promise)
51+
public function wait(Promise $promise, callable $onProgress = null)
5152
{
5253
if (!$this->isThenable($promise)) {
53-
return;
54+
throw new \InvalidArgumentException(sprintf('The "%s" method must be call with compatible a Promise.', __METHOD__));
5455
}
5556
$wait = true;
5657
$resolvedValue = null;
5758
$exception = null;
5859
/** @var \React\Promise\PromiseInterface $reactPromise */
5960
$reactPromise = $promise->adoptedPromise;
6061

62+
$reactPromise->then(function ($values) use (&$resolvedValue, &$wait) {
63+
$resolvedValue = $values;
64+
$wait = false;
65+
}, function ($reason) use (&$exception, &$wait) {
66+
$exception = $reason;
67+
$wait = false;
68+
});
69+
70+
// wait until promise resolution
6171
while ($wait) {
62-
$reactPromise->then(function ($values) use (&$resolvedValue, &$wait) {
63-
$resolvedValue = $values;
64-
$wait = false;
65-
}, function ($reason) use (&$exception, &$wait) {
66-
$exception = $reason;
67-
$wait = false;
68-
});
72+
if (null !== $onProgress) {
73+
$onProgress();
74+
}
75+
// less CPU intensive without sacrificing the performance
76+
usleep(5);
6977
}
7078

71-
if ($exception instanceof \Exception) {
79+
/** @var \Exception|null $exception */
80+
if (null !== $exception) {
7281
throw $exception;
7382
}
7483

ExpressionLanguage/AuthorizationExpressionProvider.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,6 @@ function () {
5252
'isFullyAuthenticated',
5353
function () {
5454
return '$container->get(\'security.authorization_checker\')->isGranted(\'IS_AUTHENTICATED_FULLY\')';
55-
},
56-
function () {
5755
}
5856
),
5957

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the OverblogGraphQLBundle package.
5+
*
6+
* (c) Overblog <http://github.com/overblog/>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Overblog\GraphQLBundle\Tests\Error;
13+
14+
use GraphQL\Executor\Promise\Promise;
15+
use Overblog\GraphQLBundle\Executor\Promise\Adapter\ReactPromiseAdapter;
16+
use Symfony\Component\Process\PhpProcess;
17+
18+
class ReactPromiseAdapterTest extends \PHPUnit_Framework_TestCase
19+
{
20+
/** @var ReactPromiseAdapter */
21+
private $adapter;
22+
23+
public function setUp()
24+
{
25+
$this->adapter = new ReactPromiseAdapter();
26+
}
27+
28+
/**
29+
* @expectedException \InvalidArgumentException
30+
* @expectedExceptionMessage The "Overblog\GraphQLBundle\Executor\Promise\Adapter\ReactPromiseAdapter::wait" method must be call with compatible a Promise.
31+
*/
32+
public function testWaitWithNotSupportedPromise()
33+
{
34+
$noSupportedPromise = new Promise(new \stdClass(), $this->adapter);
35+
$this->adapter->wait($noSupportedPromise);
36+
}
37+
38+
/**
39+
* @expectedException \Exception
40+
* @expectedExceptionMessage Promise has been rejected!
41+
*/
42+
public function testWaitRejectedPromise()
43+
{
44+
$rejected = $this->adapter->createRejected(new \Exception('Promise has been rejected!'));
45+
$this->adapter->wait($rejected);
46+
}
47+
48+
public function testWaitAsyncPromise()
49+
{
50+
$output = 'OK!';
51+
$process = new PhpProcess(<<<EOF
52+
<?php
53+
usleep(30);
54+
echo '$output';
55+
EOF
56+
);
57+
58+
$promise = $this->adapter->create(function (callable $resolve) use (&$process) {
59+
$process->start(function () use ($resolve, &$process) {
60+
$output = $process->getOutput();
61+
$resolve($output);
62+
});
63+
});
64+
65+
$this->assertEquals(
66+
$output,
67+
$this->adapter->wait($promise, function () use (&$process) {
68+
$process->wait();
69+
})
70+
);
71+
}
72+
}

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"webonyx/graphql-php": "^0.9.0"
4040
},
4141
"suggest": {
42-
"twig/twig": "If you want to use graphiQL."
42+
"twig/twig": "If you want to use graphiQL.",
43+
"react/promise": "To use ReactPHP promise adapter"
4344
},
4445
"require-dev": {
4546
"friendsofphp/php-cs-fixer": "^1.11",

0 commit comments

Comments
 (0)