Skip to content

Async Execution Strategy#242

Closed
dminkovsky wants to merge 7 commits intographql-java:masterfrom
dminkovsky:async
Closed

Async Execution Strategy#242
dminkovsky wants to merge 7 commits intographql-java:masterfrom
dminkovsky:async

Conversation

@dminkovsky
Copy link
Contributor

@dminkovsky dminkovsky commented Nov 16, 2016

A Java 8 CompletableFuture-based async execution strategy.

The API is:

GraphQLSchema schema;

GraphQL graphql = new GraphQL(
  schema,
  AsyncExecutionStrategy.parallel(),
  AsyncExecutionStrategy.serial()
);

ExecutionResult result = graphql.execute("... some query ...");
        
CompletionStage<Map<String, Object>> data = (CompletionStage<Map<String, Object>>) result.getData();
        
data.thenAccept(data -> {

    // ... use `data`: a `Map<String, Object>` where the values are all complete results 

    List<GraphQLError> errors = result.getErrors();

    // ... use `errors`
});

Data fetchers can return synchronously or asynchronously (by returning a CompletionState).

This strategy requires Java 8, but uses the existing core graphql-java execution API without any changes. It will have to be broken out as a sub-module with its own artifact for Java 8 users wanting to use this strategy.

Still missing:

  • timeout configuration
  • executor service configuration

Still thinking about the tests.

Looking forward to your thoughts. Thank you.

@dminkovsky
Copy link
Contributor Author

Will re-open with much simpler implementation soon.

@dminkovsky dminkovsky closed this Dec 8, 2016
private Map<String, Object> variables = new LinkedHashMap<String, Object>();
private Object root;
private List<GraphQLError> errors = new ArrayList<GraphQLError>();
private List<GraphQLError> errors = Collections.synchronizedList(new ArrayList<GraphQLError>());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CopyOnWriteArrayList is pretty efficient list

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure Collections.synchronizedList() is good here anyway. Thanks, I'll check out CopyOnWriteArrayList

this(graphQLSchema, queryStrategy, null);
}

public GraphQL(GraphQLSchema graphQLSchema, ExecutionStrategy queryStrategy, ExecutionStrategy mutationStrategy) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GraphQL spec says that mutations WILL ALWAYS be serial. So why allow people to wire in anything BUT a serial implementation?

I guess it makes it more configureable than today but you have no way of knowing that they are following spec or not.

Maybe its a case of "dont shoot yourself" by wiring in a asynch mutation execution strategy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My serial implementation is async. The current serial implementation is not async. Both are serial though.

@bbakerman
Copy link
Member

BTW you are not far of the mark in terms of implementation. Here is an example from Shopify. Its much like yours in that a Promise (CompletableFuture) is return and understood by the executoinStrategy

https://github.com/Shopify/graphql-batch

@He-Pin
Copy link

He-Pin commented Dec 11, 2016

I am currently using monix to implement.

import java.util.concurrent.CompletionStage;
import java.util.function.Supplier;

import static com.spotify.futures.CompletableFutures.successfulAsList;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you really want Spotify as a dependency. I thought graphql-java was trying to be as lightweight as possible

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's just in there while I work this out. That artifact is tiny (50 LOC?) and can be copy/pasted into this project license-permitting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking a look!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants