-
-
Notifications
You must be signed in to change notification settings - Fork 565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using with dataloader-php throws "Could not resolve promise" Exception #150
Comments
I am curious, have you tried the same with just Looks like DataLoader project wraps original adapter, so it's hard to say without digging deeper if this is a bug in this library or in DataLoader. @mcg-web any thoughts? |
@vladar Could you give me an example on how I could achieve something like the code I added in my last edit with I will try to setup a reproduction repository using laravel-graphql and dataloader-php. |
@mcg-web Here is my reproduction repository: https://github.com/n1ru4l/laravel-graphql-dataloader-php-exception-reproduction The relevant files are the Service Provider ( You will not need any database setup just use You can navigate to This query fails: query type1 {
type1 {
__typename
id
items {
__typename
id
items {
__typename
id
items {
__typename
id
}
}
}
} This query works: query type1 {
type1 {
__typename
id
items {
__typename
id
}
}
} |
I forked your repo and replaced DataLoaders with regular I guess the bug is somewhere on DataLoader side. |
@vladar Thank you for the fast response :) Is there any option to move this issue to dataloader-php repository? |
I am trying to get why @n1ru4l . if I don't get i'll create the issue on dataloader repository :) |
OK cool, also thank you for the fast responses :) |
@mcg-web If I add /**
* Synchronously wait when promise completes
*
* @param Promise $promise
* @return mixed
*/
public function wait(Promise $promise)
{
$dfdQueue = Deferred::getQueue();
$promiseQueue = SyncPromise::getQueue();
while (
$promise->adoptedPromise->state === SyncPromise::PENDING &&
!($dfdQueue->isEmpty() && $promiseQueue->isEmpty())
) {
Deferred::runQueue();
SyncPromise::runQueue();
DataLoader::await();
}
/** @var SyncPromise $syncPromise */
$syncPromise = $promise->adoptedPromise;
if ($syncPromise->state === SyncPromise::FULFILLED) {
return $syncPromise->result;
} else if ($syncPromise->state === SyncPromise::REJECTED) {
throw $syncPromise->result;
}
throw new InvariantViolation("Could not resolve promise");
} So the whole queue must be progressed together. I guess you guys will have to write your own Obviously, I am not 100% sure that this is enough to fix it (as I am not aware of But let me know if I can make it easier for you somehow (e.g. by changing an interface of SyncPromiseAdapter or maybe changing how Executor calls |
Yes that where the bug is coming from, thank you. it works if we add the dataloader::await but only if we keep the wait of the override method |
here a solution that works:
// src/Executor/Promise/Adapter/SyncPromiseAdapter.php
/**
* Synchronously wait when promise completes
*
* @param Promise $promise
* @return mixed
*/
public function wait(Promise $promise)
{
$this->beforeWait($promise);
$dfdQueue = Deferred::getQueue();
$promiseQueue = SyncPromise::getQueue();
while (
$promise->adoptedPromise->state === SyncPromise::PENDING &&
!($dfdQueue->isEmpty() && $promiseQueue->isEmpty())
) {
Deferred::runQueue();
SyncPromise::runQueue();
$this->onWait($promise);
}
/** @var SyncPromise $syncPromise */
$syncPromise = $promise->adoptedPromise;
if ($syncPromise->state === SyncPromise::FULFILLED) {
return $syncPromise->result;
} else if ($syncPromise->state === SyncPromise::REJECTED) {
throw $syncPromise->result;
}
throw new InvariantViolation("Could not resolve promise");
}
/**
* Execute just before starting to run promise completion
*
* @param Promise $promise
*/
protected function beforeWait(Promise $promise)
{
}
/**
* While running promise completion
*
* @param Promise $promise
*/
protected function onWait(Promise $promise)
{
}
protected function beforeWait(Promise $promise)
{
DataLoader::await();
}
protected function onWait(Promise $promise)
{
DataLoader::await();
} @vladar tell me what do you think of this solution please? |
Works for me, pragmatically %) Can anyone prepare PR for this? I'll merge it. |
I'll submit it, thank you @vladar ;) |
Thanks! Merged and released 0.9.14 |
thanks again ;) |
@n1ru4l new release here, also require to update graphql to 0.9.14 (graphql is not a requirement of the lib)... |
Thank you so much 😊 I will check that out on monday!
…On Aug 18, 2017 7:23 PM, "Jeremiah VALERIE" ***@***.***> wrote:
@n1ru4l <https://github.com/n1ru4l> new release here
<https://github.com/overblog/dataloader-php/releases/tag/v0.5.2>, also
require to update graphql to 0.9.14 (graphql is not a requirement of the
lib)...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#150 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ANrH1_4Qa-8cXzOQLexbkYNfMnPmglLVks5sZciMgaJpZM4O6OO2>
.
|
Closing this. Feel free to re-open if it is still broken. |
I have three types
Every field that returns a list uses a DataLoader (like in https://github.com/overblog/dataloader-php#using-with-webonyxgraphql). Each DataLoader is identical, despite the tables from which the dataloaders fetch their data.
The following query works fine:
However going one level deeper results in an exception.
When I log the status of the promise I get pending.
According to the code this should not happen. https://github.com/webonyx/graphql-php/blob/master/src/Executor/Promise/Adapter/SyncPromiseAdapter.php#L132
When I use the following query (only 2 dataloader) everything is behaving like excpected:
Edit: This also happens in this resolver function where I chain multiple promises (I am using laravel):
The text was updated successfully, but these errors were encountered: