Search code examples
rx-java2vert.xgraphql-java

Vertx web and graphql


There are a couple of queries that I want to get clarified.

  1. We are deploying multiple instances (20) of the verticle and that will create multiple instances of GraphQLHandler. Is that ok or should we stick to just one instance of GraphQLHandler ?
// Inside the constructor of the verticle
this.graphQLHandler = GraphQLHandler.create(createGraphQL(), new GraphQLHandlerOptions().setRequestBatchingEnabled(true));
private GraphQL createGraphQL() {
        log.info("**** Loading the graphQL schema ****");
        String schema = vertx.fileSystem().readFileBlocking("tetris.graphqls").toString();
        SchemaParser schemaParser = new SchemaParser();
        TypeDefinitionRegistry typeDefinitionRegistry = schemaParser.parse(schema);
        RuntimeWiring runtimeWiring = newRuntimeWiring()
                .wiringFactory(new WiringFactory() {
                    @Override
                    public DataFetcher getDefaultDataFetcher(FieldWiringEnvironment environment) {
                        return new VertxPropertyDataFetcher(environment.getFieldDefinition().getName());
                    }
                })
                .scalar(ScalarDataTypes.instantScalar)
                .scalar(ExtendedScalars.Json)
                .type("Query", builder -> {
                    VertxDataFetcher<JsonObject> getArrangementDetailsByLegacyCodeAndEffectiveDate = new VertxDataFetcher<>(this::getArrangementDetailsByLegacyCodeAndEffectiveDate);
                    return builder
                            .dataFetcher("getArrangementDetailsByLegacyCodeAndEffectiveDate", getArrangementDetailsByLegacyCodeAndEffectiveDate);

                })
                .build();
        SchemaGenerator schemaGenerator = new SchemaGenerator();
        GraphQLSchema graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring);
        return GraphQL.newGraphQL(graphQLSchema).build();
    }
  1. We are using rxjava to fetch the result and returning the promise. When we return the promise, the execution is happening on rxjava thread. We want to move that to event loop. How can that be achieved.
private void getArrangementDetailsByLegacyCodeAndEffectiveDate(DataFetchingEnvironment dataFetchingEnvironment, Promise<JsonObject> promise) {
 Scheduler scheduler = RxHelper.scheduler(vertx.getOrCreateContext());

 Handler<AsyncResult<JsonObject>> resultHandler = handler -> {
                if (handler.succeeded()) {
                    promise.complete(handler.result());
                } else {
                    log.error(new LogEvent("graphql_subscribe_error", traceId).addThrowable(handler.cause()).toString());
                    promise.fail(handler.cause());
                }
            };

 getArrangementsFlowable.
   ...
  .subscribeOn(scheduler)
  .subscribe(SingleHelper.toObserver(resultHandler));

}

Logs:

01:04:05.520 [RxCachedThreadScheduler-3] DEBUG graphql.execution.ExecutionStrategy - '70fad529-b19b-426a-8f7c-82a4a3d0b9ea' completing field '/getArrangementDetailsByLegacyCodeAndEffectiveDate'...
01:04:05.520 [RxCachedThreadScheduler-3] DEBUG graphql.execution.ExecutionStrategy - '70fad529-b19b-426a-8f7c-82a4a3d0b9ea' fetching field '/getArrangementDetailsByLegacyCodeAndEffectiveDate/effective_timestamp' using data fetcher 'io.vertx.ext.web.handler.graphql.VertxPropertyDataFetcher'...
01:04:05.520 [RxCachedThreadScheduler-3] DEBUG n.g.execution.ExecutionStrategy - '70fad529-b19b-426a-8f7c-82a4a3d0b9ea' field '/getArrangementDetailsByLegacyCodeAndEffectiveDate/effective_timestamp' fetch returned 'java.lang.String'
01:04:05.520 [RxCachedThreadScheduler-3] DEBUG graphql.execution.ExecutionStrategy - '70fad529-b19b-426a-8f7c-82a4a3d0b9ea' completing field '/getArrangementDetailsByLegacyCodeAndEffectiveDate/effective_timestamp'...
01:04:05.520 [RxCachedThreadScheduler-3] DEBUG graphql.execution.ExecutionStrategy - '70fad529-b19b-426a-8f7c-82a4a3d0b9ea' fetching field '/getArrangementDetailsByLegacyCodeAndEffectiveDate/end_timestamp' using data fetcher 'io.vertx.ext.web.handler.graphql.VertxPropertyDataFetcher'...
01:04:05.520 [RxCachedThreadScheduler-3] DEBUG n.g.execution.ExecutionStrategy - '70fad529-b19b-426a-8f7c-82a4a3d0b9ea' field '/getArrangementDetailsByLegacyCodeAndEffectiveDate/end_timestamp' fetch returned 'java.lang.String'

Solution

    1. It is fine to create multiple instances of GraphQLHandler
    2. In order to get items processed on the event loop, use the observeOn operator, not subscribeOn