-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Singletons are created twice when observers subsystem is used #2673
Comments
Ok. So the problem is that The ordering of context destruction is not defined so even if we try to avoid this particular use case, another problem could be with an It should be save to use Anyway, I think it would make sense to modify the |
Actually, it's probably not a good idea. We should only do this if |
Thank you @mkouba for a detailed explanation. Can I workaround this somehow? Some workaround I can think of would be to simply ignore this scenario and skip the event since it's useless for me at this stage (since whole stack is already terminated). Can I do something like: public class MagicObserver {
private final MagicSystem system;
public MagicObserver() {
if (isScopeActive()) {
this.system = CDI.current().select(MagicSystem.class).get();
} else {
this.system = null;
}
}
private boolean isScopeActive() {
return // can I check if scope is active or destroyed here?
}
public void observe(@Observes Object event) {
if (system != null) {
System.out.println("observed " + event + " " + system);
}
}
} The other w/a (but the ugliest one I can think of) would be to somehow destroy my non-managed bean. When I worked with HK2 I was able to have factory with producer and destroyer methods, e.g: @Service
public class SomeSystemFactory implements Factory<SomeSystem> {
@Override
@Singleton
public SomeSystem provide() {
return SomeSystem.create(name, config.get());
}
@Override
public void dispose(SomeSystem system) {
system.terminate();
}
} By doing this I could destroy my bean in a clear way (i.e. close ports, sockets, etc) and, if there is no other option, let it be created again, even just for a moment. |
You can also use disposer methods for producers in CDI. See for example https://github.com/quarkusio/quarkus/blob/master/independent-projects/arc/tests/src/test/java/io/quarkus/arc/test/producer/disposer/DisposerTest.java#L89-L92. For WRT workaround: 1) use |
Thank you @mkouba! I already tried using @Dependent
public class MagicObserver {
private final MagicSystem system;
@Inject
public MagicObserver(final MagicSystem system) {
this.system = system;
}
public void observe(@Observes Object event) {
System.out.println("observed " + event);
}
} The problem in fact is not with the multiple instances of This is weird because in EventImpl.createNotifier(Object.class, Object.class, destroyQualifiers, this).notify(toString());
singletonContext.destroy(); |
Yes, because when |
I confirm that change from mkouba@a2e0dbc fixed described problem. |
Thank you @mkouba :) |
Describe the bug
Singletons by definition should be created only once, however, in the scenario I describe in the next section I managed to make Quarkus create singleton beans twice.
Expected behavior
Singletons are singletons (single instances of a bean).
Actual behavior
Singletons are twinletons (two instances of the same bean).
To Reproduce
Have a non-managed bean:
Have another bean, a
@Singleton
with a producer method:And have observer bean with observer method:
And a very simple test just to bootstrap Quarkus:
After test is run you will observe
IllegalStateException
with message "I should be singleton, dude!" which indicates that bean was created more than once which is not expected since all these beans are singletons and as such should be a single instances.The
new Error().printStackTrace()
inMagicSystemFactory
helps us narrow down the problem and we can see that first singletons are created on test initialization and the second ones are created when test is stopped.When observer method is commented out, the code works as expected!
Configuration
N/A
Screenshots
N/A/
Environment (please complete the following information):
Quarkus revision:
Additional context
Found when playing with my project available here https://github.com/sarxos/abberwoult
The text was updated successfully, but these errors were encountered: