Skip to content
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

Graphql client initializing VertX cache even with vertx caching disabled #28875

Closed
syr opened this issue Oct 27, 2022 · 17 comments · Fixed by #29375
Closed

Graphql client initializing VertX cache even with vertx caching disabled #28875

syr opened this issue Oct 27, 2022 · 17 comments · Fixed by #29375

Comments

@syr
Copy link

syr commented Oct 27, 2022

Describe the bug

With latest Quarkus 2.13.3.Final, when using quarkus-smallrye-graphql-client with vertx caching disabled by

quarkus.vertx.caching=false
quarkus.vertx.classpath-resolving=false

Starting quarkus application in docker with readonly fs by

docker run -i --rm -p 8080:8080 --read-only quarkus/code-with-quarkus-jvm

I get error

 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2022-10-27 09:35:26,871 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.nio.file.FileSystemException: /tmp/vertx-cache-81092607-e0a3-49c4-8734-213cba4c7b4d: Read-only file system
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:397)
        at java.base/java.nio.file.Files.createDirectory(Files.java:700)
        at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:807)
        at java.base/java.nio.file.Files.createDirectories(Files.java:793)
        at io.vertx.core.file.impl.FileCache.setupCacheDir(FileCache.java:58)
        at io.vertx.core.file.impl.FileCache.setupCache(FileCache.java:31)
        at io.vertx.core.file.impl.FileResolverImpl.<init>(FileResolverImpl.java:67)
        at io.vertx.core.impl.VertxBuilder.initFileResolver(VertxBuilder.java:334)
        at io.vertx.core.impl.VertxBuilder.init(VertxBuilder.java:274)
        at io.vertx.core.Vertx.vertx(Vertx.java:87)
        at io.vertx.core.Vertx.vertx(Vertx.java:77)
        at io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder.build(VertxDynamicGraphQLClientBuilder.java:133)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients.lambda$getClient$0(NamedDynamicClients.java:41)
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients.getClient(NamedDynamicClients.java:40)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients_ProducerMethod_getClient_1a472307edb2c0c36e1f2fc6b46eeac419bdaed8_Bean.create(Unknown Source)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients_ProducerMethod_getClient_1a472307edb2c0c36e1f2fc6b46eeac419bdaed8_Bean.get(Unknown Source)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients_ProducerMethod_getClient_1a472307edb2c0c36e1f2fc6b46eeac419bdaed8_Bean.get(Unknown Source)
        at io.quarkus.arc.impl.CurrentInjectionPointProvider.get(CurrentInjectionPointProvider.java:62)
        at client.StarWarsResource_Bean.create(Unknown Source)
        at client.StarWarsResource_Bean.create(Unknown Source)

Not sure if graphql client does not work with disabled vertx cache or if it is missing to respect

quarkus.vertx.caching=false
quarkus.vertx.classpath-resolving=false

Reproducer based on microprofile-graphql-client-quickstart: https://github.com/syr/code-with-quarkus

Expected behavior

Quarkus application should start up and use graphql client without errors.

Actual behavior

 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2022-10-27 09:35:26,871 ERROR [io.qua.run.Application] (main) Failed to start application (with profile prod): java.nio.file.FileSystemException: /tmp/vertx-cache-81092607-e0a3-49c4-8734-213cba4c7b4d: Read-only file system
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:397)
        at java.base/java.nio.file.Files.createDirectory(Files.java:700)
        at java.base/java.nio.file.Files.createAndCheckIsDirectory(Files.java:807)
        at java.base/java.nio.file.Files.createDirectories(Files.java:793)
        at io.vertx.core.file.impl.FileCache.setupCacheDir(FileCache.java:58)
        at io.vertx.core.file.impl.FileCache.setupCache(FileCache.java:31)
        at io.vertx.core.file.impl.FileResolverImpl.<init>(FileResolverImpl.java:67)
        at io.vertx.core.impl.VertxBuilder.initFileResolver(VertxBuilder.java:334)
        at io.vertx.core.impl.VertxBuilder.init(VertxBuilder.java:274)
        at io.vertx.core.Vertx.vertx(Vertx.java:87)
        at io.vertx.core.Vertx.vertx(Vertx.java:77)
        at io.smallrye.graphql.client.vertx.dynamic.VertxDynamicGraphQLClientBuilder.build(VertxDynamicGraphQLClientBuilder.java:133)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients.lambda$getClient$0(NamedDynamicClients.java:41)
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients.getClient(NamedDynamicClients.java:40)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients_ProducerMethod_getClient_1a472307edb2c0c36e1f2fc6b46eeac419bdaed8_Bean.create(Unknown Source)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients_ProducerMethod_getClient_1a472307edb2c0c36e1f2fc6b46eeac419bdaed8_Bean.get(Unknown Source)
        at io.smallrye.graphql.client.impl.dynamic.cdi.NamedDynamicClients_ProducerMethod_getClient_1a472307edb2c0c36e1f2fc6b46eeac419bdaed8_Bean.get(Unknown Source)
        at io.quarkus.arc.impl.CurrentInjectionPointProvider.get(CurrentInjectionPointProvider.java:62)
        at client.StarWarsResource_Bean.create(Unknown Source)
        at client.StarWarsResource_Bean.create(Unknown Source)

How to Reproduce?

Reproducer based on microprofile-graphql-client-quickstart: https://github.com/syr/code-with-quarkus

Reproduced by

mvn clean install

docker build -f src/main/docker/Dockerfile.jvm -t quarkus/code-with-quarkus-jvm .

docker run -i --rm -p 8080:8080 --read-only quarkus/code-with-quarkus-jvm

Output of uname -a or ver

No response

Output of java -version

openjdk version "17.0.2" 2022-01-18 OpenJDK Runtime Environment Temurin-17.0.2+8 (build 17.0.2+8) OpenJDK 64-Bit Server VM Temurin-17.0.2+8 (build 17.0.2+8, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.13.3.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.2

Additional information

related to #28094

@quarkus-bot
Copy link

quarkus-bot bot commented Oct 27, 2022

/cc @gwenneg, @jmartisk, @phillip-kruger

@jmartisk
Copy link
Contributor

This seems to happen because the client builder isn't able to locate the existing Vert.x instance (managed by Quarkus) and thus it builds a new one for itself (and in such case the configuration won't be applied, it is just created with default settings).
I'll need to check why the builder can't locate it.

@jmartisk
Copy link
Contributor

The problem is related to the fact that you're invoking the GraphQL client in a @Observes StartupEvent method: https://github.com/syr/code-with-quarkus/blob/main/src/main/java/client/StarWarsResource.java#L52
At that point, the Quarkus-managed Vert.x instance seems to not be fully initialized, so when the GraphQL client library attempts to find it using Vertx.currentContext(), that doesn't work.
If I remove the startup-event method and instead use a REST method to trigger the GraphQL client's work after the application is fully started, it works.

I'm not sure if this can be resolved though - the fix would probably be somewhere in the Vert.x extension. Hopefully @cescoffier can comment.

@jmartisk
Copy link
Contributor

Or maybe the Vertx instance is initialized, but the Vertx.currentContext() call can't find it because the thread executing the startup method isn't set up for this?
In any case, if you refrain from using the startup task, it will work.

@geoand
Copy link
Contributor

geoand commented Oct 27, 2022

I am very surprised by this behavior as things like this should just work.

Also TBH, I think the problem is different as vertx is never set in VertxDynamicGraphQLClientBuilder which result in a new instance of Vert.x being created.

@syr
Copy link
Author

syr commented Oct 27, 2022

The problem is related to the fact that you're invoking the GraphQL client in a @Observes StartupEvent method: https://github.com/syr/code-with-quarkus/blob/main/src/main/java/client/StarWarsResource.java#L52

Should not be related to the startup event, I only put it there to show the issue in the reproducer.
The problem occured in the actual productive code yesterday as soon as we included graphql client and used it in our code, where it is not called in startup event but by a service method, called by a quartz job.

@jmartisk
Copy link
Contributor

jmartisk commented Oct 27, 2022

I think the problem is different as vertx is never set in VertxDynamicGraphQLClientBuilder which result in a new instance of Vert.x being created.

If it's not set, the library tries to use Vertx.currentContext() to find it:
https://github.com/smallrye/smallrye-graphql/blob/1.7.1/client/implementation-vertx/src/main/java/io/smallrye/graphql/client/vertx/dynamic/VertxDynamicGraphQLClientBuilder.java#L128

If this doesn't work in Quartz either, then the problem is really that the threads executing the startup callback and Quartz events are not set up to see the Vert.x context. But I don't know how we should attempt to locate it in such case. Perhaps some recorder action that stores a reference to the Vertx instance into a static variable during boot? I can try experimenting with it next week.

@geoand
Copy link
Contributor

geoand commented Oct 28, 2022

Vert.x integration does work in these settings, otherwise most of out other extensions would fail

@syr
Copy link
Author

syr commented Oct 31, 2022

OK, thanks for the update, I just tested without startup event or quartz, calling graphql client directly in rest resource where the issue does not occur, confirming it is scoped (at least) to quartz, startup event whereas IMO quartz is more critical than startup event which has limited usages of graphql client (I assume)

@jmartisk
Copy link
Contributor

Btw. as a workaround, you should be able to @Inject Vertx vertx (or CDI.current().select(Vertx.class)) and pass that instance to the GraphQL client builder that you instantiate yourself (so you build a client manually instead of injecting one that is configured in application.properties)

@syr
Copy link
Author

syr commented Nov 1, 2022

@jmartisk Thanks a lot for the workaround. :) Will give it a try soon.

@jmartisk
Copy link
Contributor

jmartisk commented Nov 4, 2022

I've submitted a PR with a potential fix, see smallrye/smallrye-graphql#1605

@cescoffier
Copy link
Member

@jmartisk when creating your own Vert.x instance for such kind of use case, I recommend:

  • disabling the async DNS resolver
  • disabling caching

@jmartisk
Copy link
Contributor

jmartisk commented Nov 7, 2022

@cescoffier good point, I'll apply that, thanks

@geoand
Copy link
Contributor

geoand commented Nov 7, 2022

Maybe we should have some common utility in Smallrye that creates such a custom Vert.x instance?

@jmartisk
Copy link
Contributor

jmartisk commented Nov 9, 2022

I don't know if any other SR project does this. If yes, then it might make sense, but AFAIK only the GraphQL client does this atm.

@jmartisk
Copy link
Contributor

jmartisk commented Nov 9, 2022

This will be resolved by upgrading to SmallRye GraphQL either 1.8.3 or 1.9.0 (there will be a little Quarkus-side code change along with it)

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

Successfully merging a pull request may close this issue.

6 participants