Skip to content

Should allow for specific CompletableFuture implementations#1

Merged
dminkovsky merged 1 commit intodminkovsky:asyncfrom
doyleyoung:async_factory
Jan 3, 2017
Merged

Should allow for specific CompletableFuture implementations#1
dminkovsky merged 1 commit intodminkovsky:asyncfrom
doyleyoung:async_factory

Conversation

@bmsantos
Copy link

@bmsantos bmsantos commented Jan 3, 2017

@dminkovsky, I've converted some code to make use of your async implementation and I'm currently playing with it.

My sample project uses Vert.x and I want to make use of Vert.x event loop threads or worker threads. It just happens that the amazing @cescoffier wrote a CompletableFuture implementation for Vertx.

Based on this I would think that one thing that its missing here is to have a way to pass a CompletableFuture factory to AsyncExecutionStrategy in order to allow other frameworks/toolkits to make best use of their threading mechanism.

What do you think?

graphql-java async implmentation should allow for non-default CompletableFeatures as
some users/frameworks/toolkits want to use their own thread pools.
@bmsantos
Copy link
Author

bmsantos commented Jan 3, 2017

Here's a usage example:

final CompletionStage<ExecutionResult> future = new GraphQLAsync(schema,
    AsyncExecutionStrategy.parallel(new VertxCompletableFutureFactory(vertx))).executeAsync(query);

feature.handle((executionResult, throwable) -> {
  System.out.println("Result: " + executionResult.getData().toString());
  System.out.println("Errors: " + executionResult.getErrors().toString());
  System.out.println("Throwable: " + throwable);
  return this;
}).toCompletableFuture();

Where the factory class looks like:

public class VertxCompletableFutureFactory implements CompletableFutureFactory {

  private final Vertx vertx;

  public VertxCompletableFutureFactory(final Vertx vertx) {
    requireNonNull(vertx);
    this.vertx = vertx;
  }

  @Override
  public <T> CompletableFuture<T> future() {
    return new VertxCompletableFuture<>(vertx);
  }
}

@dminkovsky
Copy link
Owner

This looks good to me! Thanks so much for the PR. Does this implementation look good to you, otherwise?

@dminkovsky dminkovsky merged this pull request into dminkovsky:async Jan 3, 2017
@bmsantos
Copy link
Author

bmsantos commented Jan 3, 2017

Yes, so far the implementation looks good. Still going through experimentation. Will keep you updated. Nice work.

@dminkovsky
Copy link
Owner

Great, thank you. If you're familiar with Spock, there is also this spec.

@bmsantos
Copy link
Author

bmsantos commented Jan 3, 2017

Yes, I will eventually add some tests. I didn't so yet because the code introduced doesn't really change the inner works and the AsyncExecutionStrategy.serial() tests it with the DefaultCompletableFutureFactory.

@bmsantos
Copy link
Author

bmsantos commented Jan 3, 2017

It would be nice to add tests for parallel as well. I'll add some in the next few days.

@dminkovsky
Copy link
Owner

Definitely. I have that @Ignored test regarding fields executing in the correct order. I left that as a reminder to ensure serial actually does switch to parallel after a mutation. But generally testing parallel mode as well will be good.

One more thing to maybe keep in mind is this: graphql-java#268.

@bmsantos
Copy link
Author

bmsantos commented Jan 3, 2017

Sounds good. Thanks for sharing.

@dminkovsky
Copy link
Owner

I'm handling graphql-java#268 for this async version now. Will update here with new commit soon.

@bmsantos
Copy link
Author

bmsantos commented Jan 4, 2017

Quick update: I can now confirm that I've successfully used this implementation with Vert.x.

Parallel implementation seems to be working just fine. My case scenario looks something like this at this stage:

                    .---------.       .---------.
  POST /graphql --> | Vertx   |       | EP1     | 
                    | GraphQL | ----> | Swagger | 
                    | Server  |  |    | Server  | 
                    '---------'  |    '---------'
                                 |    .---------. 
                                 |    | EP2     | 
                                 '--> | Swagger | 
                                      | Server  | 
                                      '---------' 

EP1 is the main query data fetcher. EP2 is a endpoint that gets called in parallel for 3 different fields in the graph. All requests for EP2 are placed in parallel (in their own thread) to its respective endpoints.

So far so good. Everything is running non-blocking and no issues have been detected.

@dminkovsky
Copy link
Owner

dminkovsky commented Jan 4, 2017

That is great to hear. I've never used Vertx or Swagger, but I'm glad you're abstracting over them (is what you'd call it?) with this implementation.

I pushed some commits to the async branch just now to fix some problems with error handling and the above-mentioned issue. Instead of squashing in force-pushing I did the opposite: the commits are small and hopefully easy to follow.

@dminkovsky
Copy link
Owner

Looks like it's broken. One sec.

@dminkovsky
Copy link
Owner

Ah, there we go. Should be good now graphql-java#283

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.

2 participants