Moved PromiseAdapter to ExecutionContext; allow passing it to Executor::execute() directly vs setting statically

This commit is contained in:
Vladimir Razuvaev 2017-07-12 19:44:04 +07:00
parent bf0a7a8e2b
commit 65d9472b0b
4 changed files with 50 additions and 57 deletions

View File

@ -1,7 +1,6 @@
<?php <?php
namespace GraphQL; namespace GraphQL;
use GraphQL\Executor\Promise\PromiseAdapter;
use GraphQL\Type\Descriptor; use GraphQL\Type\Descriptor;
use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ObjectType;
@ -51,11 +50,6 @@ class Config
*/ */
public $typeLoader; public $typeLoader;
/**
* @var PromiseAdapter
*/
public $promiseAdapter;
/** /**
* @param array $options * @param array $options
* @return Config * @return Config
@ -126,15 +120,6 @@ class Config
); );
$config->setDescriptor($options['descriptor']); $config->setDescriptor($options['descriptor']);
} }
if (isset($options['promiseAdapter'])) {
Utils::invariant(
$options['promiseAdapter'] instanceof PromiseAdapter,
'Promise adapter must be an instance of GraphQL\Executor\Promise\PromiseAdapter but got: %s',
Utils::getVariableType($options['promiseAdapter'])
);
$config->setPromiseAdapter($options['promiseAdapter']);
}
} }
return $config; return $config;
@ -283,22 +268,4 @@ class Config
$this->typeLoader = $typeLoader; $this->typeLoader = $typeLoader;
return $this; return $this;
} }
/**
* @return PromiseAdapter
*/
public function getPromiseAdapter()
{
return $this->promiseAdapter;
}
/**
* @param PromiseAdapter $promiseAdapter
* @return Config
*/
public function setPromiseAdapter($promiseAdapter)
{
$this->promiseAdapter = $promiseAdapter;
return $this;
}
} }

View File

@ -54,7 +54,17 @@ class ExecutionContext
*/ */
public $errors; public $errors;
public function __construct($schema, $fragments, $root, $contextValue, $operation, $variables, $errors, $fieldResolver) public function __construct(
$schema,
$fragments,
$root,
$contextValue,
$operation,
$variables,
$errors,
$fieldResolver,
$promiseAdapter
)
{ {
$this->schema = $schema; $this->schema = $schema;
$this->fragments = $fragments; $this->fragments = $fragments;
@ -64,6 +74,7 @@ class ExecutionContext
$this->variableValues = $variables; $this->variableValues = $variables;
$this->errors = $errors ?: []; $this->errors = $errors ?: [];
$this->fieldResolver = $fieldResolver; $this->fieldResolver = $fieldResolver;
$this->promises = $promiseAdapter;
} }
public function addError(Error $error) public function addError(Error $error)

View File

@ -88,6 +88,8 @@ class Executor
} }
/** /**
* Executes DocumentNode against given schema
*
* @param Schema $schema * @param Schema $schema
* @param DocumentNode $ast * @param DocumentNode $ast
* @param $rootValue * @param $rootValue
@ -95,6 +97,8 @@ class Executor
* @param array|\ArrayAccess $variableValues * @param array|\ArrayAccess $variableValues
* @param null $operationName * @param null $operationName
* @param callable $fieldResolver * @param callable $fieldResolver
* @param PromiseAdapter $promiseAdapter
*
* @return ExecutionResult|Promise * @return ExecutionResult|Promise
*/ */
public static function execute( public static function execute(
@ -104,7 +108,8 @@ class Executor
$contextValue = null, $contextValue = null,
$variableValues = null, $variableValues = null,
$operationName = null, $operationName = null,
$fieldResolver = null callable $fieldResolver = null,
PromiseAdapter $promiseAdapter = null
) )
{ {
if (null !== $variableValues) { if (null !== $variableValues) {
@ -120,7 +125,7 @@ class Executor
); );
} }
$promiseAdapter = self::getPromiseAdapter(); $promiseAdapter = $promiseAdapter ?: self::getPromiseAdapter();
try { try {
$exeContext = self::buildExecutionContext( $exeContext = self::buildExecutionContext(
@ -130,7 +135,8 @@ class Executor
$contextValue, $contextValue,
$variableValues, $variableValues,
$operationName, $operationName,
$fieldResolver $fieldResolver,
$promiseAdapter
); );
} catch (Error $e) { } catch (Error $e) {
if ($promiseAdapter instanceof SyncPromiseAdapter) { if ($promiseAdapter instanceof SyncPromiseAdapter) {
@ -151,7 +157,7 @@ class Executor
} }
/** /**
* Constructs a ExecutionContext object from the arguments passed to * Constructs an ExecutionContext object from the arguments passed to
* execute, which we will pass throughout the other execution methods. * execute, which we will pass throughout the other execution methods.
* *
* @param Schema $schema * @param Schema $schema
@ -161,6 +167,7 @@ class Executor
* @param $rawVariableValues * @param $rawVariableValues
* @param string $operationName * @param string $operationName
* @param callable $fieldResolver * @param callable $fieldResolver
* @param PromiseAdapter $promiseAdapter
* *
* @return ExecutionContext * @return ExecutionContext
* @throws Error * @throws Error
@ -172,7 +179,8 @@ class Executor
$contextValue, $contextValue,
$rawVariableValues, $rawVariableValues,
$operationName = null, $operationName = null,
$fieldResolver = null callable $fieldResolver = null,
PromiseAdapter $promiseAdapter = null
) )
{ {
$errors = []; $errors = [];
@ -225,7 +233,8 @@ class Executor
$operation, $operation,
$variableValues, $variableValues,
$errors, $errors,
$fieldResolver ?: self::$defaultFieldResolver $fieldResolver ?: self::$defaultFieldResolver,
$promiseAdapter ?: self::getPromiseAdapter()
); );
return $exeContext; return $exeContext;
} }
@ -244,16 +253,14 @@ class Executor
* Executor constructor. * Executor constructor.
* *
* @param ExecutionContext $context * @param ExecutionContext $context
* @param PromiseAdapter $promiseAdapter
*/ */
private function __construct(ExecutionContext $context, PromiseAdapter $promiseAdapter) private function __construct(ExecutionContext $context)
{ {
if (!self::$UNDEFINED) { if (!self::$UNDEFINED) {
self::$UNDEFINED = Utils::undefined(); self::$UNDEFINED = Utils::undefined();
} }
$this->exeContext = $context; $this->exeContext = $context;
$this->promises = $promiseAdapter;
} }
/** /**
@ -268,7 +275,7 @@ class Executor
// field and its descendants will be omitted, and sibling fields will still // field and its descendants will be omitted, and sibling fields will still
// be executed. An execution which encounters errors will still result in a // be executed. An execution which encounters errors will still result in a
// resolved Promise. // resolved Promise.
$result = $this->promises->create(function (callable $resolve) { $result = $this->exeContext->promises->create(function (callable $resolve) {
return $resolve($this->executeOperation($this->exeContext->operation, $this->exeContext->rootValue)); return $resolve($this->executeOperation($this->exeContext->operation, $this->exeContext->rootValue));
}); });
return $result return $result
@ -375,7 +382,7 @@ class Executor
*/ */
private function executeFieldsSerially(ObjectType $parentType, $sourceValue, $path, $fields) private function executeFieldsSerially(ObjectType $parentType, $sourceValue, $path, $fields)
{ {
$prevPromise = $this->promises->createFulfilled([]); $prevPromise = $this->exeContext->promises->createFulfilled([]);
$process = function ($results, $responseName, $path, $parentType, $sourceValue, $fieldNodes) { $process = function ($results, $responseName, $path, $parentType, $sourceValue, $fieldNodes) {
$fieldPath = $path; $fieldPath = $path;
@ -461,7 +468,7 @@ class Executor
$keys = array_keys($assoc); $keys = array_keys($assoc);
$valuesAndPromises = array_values($assoc); $valuesAndPromises = array_values($assoc);
$promise = $this->promises->all($valuesAndPromises); $promise = $this->exeContext->promises->all($valuesAndPromises);
return $promise->then(function($values) use ($keys) { return $promise->then(function($values) use ($keys) {
$resolvedResults = []; $resolvedResults = [];
@ -788,7 +795,7 @@ class Executor
if ($promise) { if ($promise) {
return $promise->then(null, function ($error) use ($exeContext) { return $promise->then(null, function ($error) use ($exeContext) {
$exeContext->addError($error); $exeContext->addError($error);
return $this->promises->createFulfilled(null); return $this->exeContext->promises->createFulfilled(null);
}); });
} }
return $completed; return $completed;
@ -832,7 +839,7 @@ class Executor
$promise = $this->getPromise($completed); $promise = $this->getPromise($completed);
if ($promise) { if ($promise) {
return $promise->then(null, function ($error) use ($fieldNodes, $path) { return $promise->then(null, function ($error) use ($fieldNodes, $path) {
return $this->promises->createRejected(Error::createLocatedError($error, $fieldNodes, $path)); return $this->exeContext->promises->createRejected(Error::createLocatedError($error, $fieldNodes, $path));
}); });
} }
return $completed; return $completed;
@ -1142,7 +1149,7 @@ class Executor
} }
$completedItems[] = $completedItem; $completedItems[] = $completedItem;
} }
return $containsPromise ? $this->promises->all($completedItems) : $completedItems; return $containsPromise ? $this->exeContext->promises->all($completedItems) : $completedItems;
} }
/** /**
@ -1299,7 +1306,7 @@ class Executor
} }
if (!empty($promisedIsTypeOfResults)) { if (!empty($promisedIsTypeOfResults)) {
return $this->promises->all($promisedIsTypeOfResults) return $this->exeContext->promises->all($promisedIsTypeOfResults)
->then(function($isTypeOfResults) use ($possibleTypes) { ->then(function($isTypeOfResults) use ($possibleTypes) {
foreach ($isTypeOfResults as $index => $result) { foreach ($isTypeOfResults as $index => $result) {
if ($result) { if ($result) {
@ -1325,12 +1332,12 @@ class Executor
if (null === $value || $value instanceof Promise) { if (null === $value || $value instanceof Promise) {
return $value; return $value;
} }
if ($this->promises->isThenable($value)) { if ($this->exeContext->promises->isThenable($value)) {
$promise = $this->promises->convertThenable($value); $promise = $this->exeContext->promises->convertThenable($value);
if (!$promise instanceof Promise) { if (!$promise instanceof Promise) {
throw new InvariantViolation(sprintf( throw new InvariantViolation(sprintf(
'%s::convertThenable is expected to return instance of GraphQL\Executor\Promise\Promise, got: %s', '%s::convertThenable is expected to return instance of GraphQL\Executor\Promise\Promise, got: %s',
get_class($this->promises), get_class($this->exeContext->promises),
Utils::printSafe($promise) Utils::printSafe($promise)
)); ));
} }

View File

@ -50,6 +50,8 @@ class GraphQL
* @param array|null $variableValues * @param array|null $variableValues
* @param string|null $operationName * @param string|null $operationName
* @param callable $fieldResolver * @param callable $fieldResolver
* @param PromiseAdapter $promiseAdapter
*
* @return Promise|array * @return Promise|array
*/ */
public static function execute( public static function execute(
@ -59,7 +61,8 @@ class GraphQL
$contextValue = null, $contextValue = null,
$variableValues = null, $variableValues = null,
$operationName = null, $operationName = null,
callable $fieldResolver = null callable $fieldResolver = null,
PromiseAdapter $promiseAdapter = null
) )
{ {
$result = self::executeAndReturnResult( $result = self::executeAndReturnResult(
@ -69,7 +72,8 @@ class GraphQL
$contextValue, $contextValue,
$variableValues, $variableValues,
$operationName, $operationName,
$fieldResolver $fieldResolver,
$promiseAdapter
); );
if ($result instanceof ExecutionResult) { if ($result instanceof ExecutionResult) {
@ -94,6 +98,8 @@ class GraphQL
* @param array|null $variableValues * @param array|null $variableValues
* @param string|null $operationName * @param string|null $operationName
* @param callable $fieldResolver * @param callable $fieldResolver
* @param PromiseAdapter $promiseAdapter
*
* @return ExecutionResult|Promise * @return ExecutionResult|Promise
*/ */
public static function executeAndReturnResult( public static function executeAndReturnResult(
@ -103,7 +109,8 @@ class GraphQL
$contextValue = null, $contextValue = null,
$variableValues = null, $variableValues = null,
$operationName = null, $operationName = null,
callable $fieldResolver = null callable $fieldResolver = null,
PromiseAdapter $promiseAdapter = null
) )
{ {
try { try {
@ -129,7 +136,8 @@ class GraphQL
$contextValue, $contextValue,
$variableValues, $variableValues,
$operationName, $operationName,
$fieldResolver $fieldResolver,
$promiseAdapter
); );
} }
} catch (Error $e) { } catch (Error $e) {