mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-25 06:16:05 +03:00
Removed memoization on executor resolveField (see #43)
This commit is contained in:
parent
0e1929f0b1
commit
3ae6c73367
@ -360,17 +360,6 @@ class Executor
|
||||
{
|
||||
$fieldAST = $fieldASTs[0];
|
||||
|
||||
$uid = self::getFieldUid($fieldAST, $parentType);
|
||||
|
||||
// Get memoized variables if they exist
|
||||
if (isset($exeContext->memoized['resolveField'][$uid])) {
|
||||
$memoized = $exeContext->memoized['resolveField'][$uid];
|
||||
$fieldDef = $memoized['fieldDef'];
|
||||
$returnType = $fieldDef->getType();
|
||||
$args = $memoized['args'];
|
||||
$info = $memoized['info'];
|
||||
}
|
||||
else {
|
||||
$fieldName = $fieldAST->name->value;
|
||||
|
||||
$fieldDef = self::getFieldDef($exeContext->schema, $parentType, $fieldName);
|
||||
@ -403,22 +392,7 @@ class Executor
|
||||
'variableValues' => $exeContext->variableValues,
|
||||
]);
|
||||
|
||||
// Memoizing results for same query field
|
||||
// (useful for lists when several values are resolved against the same field)
|
||||
$exeContext->memoized['resolveField'][$uid] = $memoized = [
|
||||
'fieldDef' => $fieldDef,
|
||||
'args' => $args,
|
||||
'info' => $info,
|
||||
'results' => new \SplObjectStorage
|
||||
];
|
||||
}
|
||||
|
||||
// When source value is object it is possible to memoize certain subset of results
|
||||
$isObject = is_object($source);
|
||||
|
||||
if ($isObject && isset($memoized['results'][$source])) {
|
||||
$result = $memoized['results'][$source];
|
||||
} else {
|
||||
if (isset($fieldDef->resolveFn)) {
|
||||
$resolveFn = $fieldDef->resolveFn;
|
||||
} else if (isset($parentType->resolveFieldFn)) {
|
||||
@ -439,11 +413,6 @@ class Executor
|
||||
$result
|
||||
);
|
||||
|
||||
if ($isObject) {
|
||||
$memoized['results'][$source] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -547,99 +547,4 @@ class ExecutorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertEquals($expected, $result->toArray());
|
||||
}
|
||||
|
||||
public function testResolvedValueIsMemoized()
|
||||
{
|
||||
$doc = '
|
||||
query Q {
|
||||
a {
|
||||
b {
|
||||
c
|
||||
d
|
||||
}
|
||||
}
|
||||
}
|
||||
';
|
||||
|
||||
$memoizedValue = new \ArrayObject([
|
||||
'b' => 'id1'
|
||||
]);
|
||||
|
||||
$A = null;
|
||||
|
||||
$Test = new ObjectType([
|
||||
'name' => 'Test',
|
||||
'fields' => [
|
||||
'a' => [
|
||||
'type' => function() use (&$A) {return Type::listOf($A);},
|
||||
'resolve' => function() use ($memoizedValue) {
|
||||
return [
|
||||
$memoizedValue,
|
||||
new \ArrayObject([
|
||||
'b' => 'id2',
|
||||
]),
|
||||
$memoizedValue,
|
||||
new \ArrayObject([
|
||||
'b' => 'id2',
|
||||
])
|
||||
];
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$callCounts = ['id1' => 0, 'id2' => 0];
|
||||
|
||||
$A = new ObjectType([
|
||||
'name' => 'A',
|
||||
'fields' => [
|
||||
'b' => [
|
||||
'type' => new ObjectType([
|
||||
'name' => 'B',
|
||||
'fields' => [
|
||||
'c' => ['type' => Type::string()],
|
||||
'd' => ['type' => Type::string()]
|
||||
]
|
||||
]),
|
||||
'resolve' => function($value) use (&$callCounts) {
|
||||
$callCounts[$value['b']]++;
|
||||
|
||||
switch ($value['b']) {
|
||||
case 'id1':
|
||||
return [
|
||||
'c' => 'c1',
|
||||
'd' => 'd1'
|
||||
];
|
||||
case 'id2':
|
||||
return [
|
||||
'c' => 'c2',
|
||||
'd' => 'd2'
|
||||
];
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
// Test that value resolved once is memoized for same query field
|
||||
$schema = new Schema($Test);
|
||||
|
||||
$query = Parser::parse($doc);
|
||||
$result = Executor::execute($schema, $query);
|
||||
$expected = [
|
||||
'data' => [
|
||||
'a' => [
|
||||
['b' => ['c' => 'c1', 'd' => 'd1']],
|
||||
['b' => ['c' => 'c2', 'd' => 'd2']],
|
||||
['b' => ['c' => 'c1', 'd' => 'd1']],
|
||||
['b' => ['c' => 'c2', 'd' => 'd2']],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $result->toArray());
|
||||
|
||||
$this->assertSame($callCounts['id1'], 1); // Result for id1 is expected to be memoized after first call
|
||||
$this->assertSame($callCounts['id2'], 2);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user