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

Get rid of the EventEmitter ThreadLocal #2133

Merged
merged 1 commit into from
Jun 25, 2024

Conversation

gsmet
Copy link
Contributor

@gsmet gsmet commented Jun 24, 2024

Part of the reasons why QuarkusClassLoader instances are kept around is the ThreadLocal in EventEmitter.

I'm not exactly sure why you are using a ThreadLocal here? The contract of the eventing services is not thread safe? I would expect them to be thread safe but I suppose there's a good reason.

In any case, I experimented with removing it and it seems to improve things quite significantly.

Now I'm not entirely sure why this was implemented in the first place so I open the PR more for discussion than to get merged right away...

/cc @phillip-kruger @cescoffier @jmartisk

This is partly responsible from our class loader leaks.
@@ -37,11 +38,13 @@
*/
public class EventEmitter {
private static final Logger LOG = Logger.getLogger(EventEmitter.class);
private static final ThreadLocal<EventEmitter> eventEmitters = ThreadLocal.withInitial(EventEmitter::new);

private static final EventEmitter INSTANCE = new EventEmitter();
Copy link
Member

Choose a reason for hiding this comment

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

This most definitely breaks multi-deployment scenarios in wildfly, because all deployments will see the same instance of the emitter. But I assume that with a ThreadLocal it was also wrong, because threads in WF are shared between applications. I'm not sure what the correct solution is, should it be a map that is keyed by the TCCL of the deployment?

(We don't care too much about multi-deployment scenarios in wildfly, but I would like it at least to be not completely broken)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The deployments share the same class loader?

Copy link
Member

Choose a reason for hiding this comment

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

When the JAR is in a static module and not part of the deployment, yes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But don’t you have the same issue in Config where you load a static config from the service loader?
Or you expect the service loader to return the same thing for all deployments?

Aware of it because I created: https://github.com/smallrye/smallrye-graphql/pull/2132/files
(which doesn’t change the behavior I think).

Copy link
Collaborator

Choose a reason for hiding this comment

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

I thought that in WildFly, threads are managed by a thread pool, so they are not shared between deployments. But I may be wrong.

Copy link
Member

@jmartisk jmartisk Jun 25, 2024

Choose a reason for hiding this comment

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

I'm thinking that I might just completely give up on trying to make it work with multiple deployments. In the JBoss EAP XP product, it's explicitly unsupported, see https://access.redhat.com/articles/2026253

Only a single microservice app (deployment) on a given server is allowed. Multiple Deployments on a given server is not supported.

(not that SmallRye GraphQL is part of the product, of course, but it makes sense to keep the policies roughly the same)

I've been putting in very limited effort to get it working, but it gets annoying because you then have to avoid most usages of static fields etc.

I thought that in WildFly, threads are managed by a thread pool, so they are not shared between deployments. But I may be wrong.

It is a thread pool that is shared by deployments. Unless you configure a separate one for each deployment, which I think would be 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.

@jmartisk I would say you have two options:

  • either you go with this patch and forget about multi-deployment
  • or you need a well defined bootstrap and the ability to propagate the instance where it's needed (what we do in HV)

In any case, the current situation is problematic: you keep the instances around and you create more than actually needed.

Copy link

Choose a reason for hiding this comment

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

Or you make this into an SPI and the Quarkus extension uses the SPI to set up a single instance instead of a TL :)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I'll probably drop multi-deployment for now. I will keep it on the basic level (both GraphQL server and client deployments should work properly as long as they don't need to have different configuration values or eventing services). Maybe revisit it in the future, but it's annoying and time-consuming to verify and test that everything works in isolation.
So yeah, a simple static field will be fine I guess.

@gsmet gsmet marked this pull request as ready for review June 25, 2024 08:20
@gsmet
Copy link
Contributor Author

gsmet commented Jun 25, 2024

Same as the other ones, ideally, it would be nice to have it in Quarkus relatively fast.
@brunobat is fighting with a PR (partly) due to these leaks.

@jmartisk jmartisk merged commit afd6873 into smallrye:main Jun 25, 2024
5 checks passed
@jmartisk
Copy link
Member

Yeah I'm on it

gsmet added a commit to gsmet/smallrye-graphql that referenced this pull request Jun 25, 2024
jmartisk pushed a commit that referenced this pull request Jun 26, 2024
jmartisk pushed a commit to jmartisk/smallrye-graphql that referenced this pull request Jun 26, 2024
jmartisk pushed a commit that referenced this pull request Jun 26, 2024
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.

4 participants