-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
ArC: add InjectableInstance.getActive() and listActive() #43803
Conversation
I know @mkouba wasn't exactly a fan, so I can be persuaded to get rid of most of this :-) |
🙈 The PR is closed and the preview is expired. |
This comment has been minimized.
This comment has been minimized.
My point is that |
To be fair, I am unsure of this as well. |
Thanks for working on this!
Yes, integrators need to determine if a bean is active or not, but those active/inactive beans are ultimately something that ordinary users need to manipulate as well. And so, some users will need to determine whether a bean is active or not. See #41810 (comment) Essentially if your app defines two datasouces, and only one of them will be active at any time, you need to be able to retrieve the active one. So yes, you can hardcode it: public class MyProducer {
@Inject
@DataSource("pg")
InjectableInstance<AgroalDataSource> pgDataSourceBean;
@Inject
@DataSource("oracle")
InjectableInstance<AgroalDataSource> oracleDataSourceBean;
@Produces
@ApplicationScoped
public AgroalDataSource dataSource() {
if (pgDataSourceBean.getHandle().getBean().isActive().result()) {
return pgDataSourceBean.get();
} else if (oracleDataSourceBean.getHandle().getBean().isActive().result()) {
return oracleDataSourceBean.get();
} else {
throw new RuntimeException("No active datasource!");
}
}
} But isn't it nice to just do this? public class MyProducer {
@Inject
@Active
AgroalDataSource activeDataSource;
@Produces
@ApplicationScoped
public AgroalDataSource dataSource() {
return activeDataSource;
}
} Or rather, if I understand this patch correctly: public class MyProducer {
@Inject
@Active
List<AgroalDataSource> activeDataSources;
@Produces
@ApplicationScoped
public AgroalDataSource dataSource() {
if (activeDataSources.size() != 1) {
throw new IllegalStateException("Number of active datasources should be 1, was " + activeDataSources.size() + " instead");
}
return activeDataSources.get(0);
}
}
If my snippet above works, then yes it would be useful. |
I don't think we can do @Inject
@Active
AgroalDataSource activeDataSource; but the last example of your comment is exactly right. |
In my opinion, for those users an default List<T> listActive() {
return handlesStream().filter(h -> h.getBean().isActive()).map(InstanceHandle::get).toList();
} and then: public class MyProducer {
@Any
InjectableInstance<AgroalDataSource> dataSources;
@Produces
@ApplicationScoped
public AgroalDataSource dataSource() {
List<AgroalDataSource> list = dataSources.listActive();
if (list.size() != 1) {
throw new IllegalStateException("Number of active datasources should be 1, was " + activeDataSources.size() + " instead");
}
return list.get(0);
}
} I mean is it really worth it? Compare the diff of this PR with the default method above... |
The above examples won't actually work - if you use an injection point with type |
EDIT: I misunderstood, you were comparing two implementations. Well, see below :) Anyway, ultimately it's up to you. You ask if it's useful, I tell you it is and show an example. If you think a different solution is superior and should be preferred for that particular use case, that's certainly your right.
Damn. @mkouba's example too? So only having one injection point per datasource would ever work? |
Confirmed, neither solution works: https://github.com/yrodiere/quarkus/commits/datasource-arc-inactive-beans-active-qualifier/ I get this in both cases:
|
Yea, Ladislav's current approach with Your example with:
Currently won't work and would require some very special handling of the IIUIC, the use case is that there can be multiple data sources but only one can be active - and your producers are basically just wrappers of existing beans enforcing that. I don't like the fact that users need to be aware of this and on top of that write a wrapper to have an injectable object. So I was thinking if we should maybe introduce a different abstraction such as:
Where users could inject this directly and the |
Yeah I'm afraid I missed that problem. I'm not sure what's the best way to cater to that use case. It seems to me that the |
I should have emphasized - what I propose assumes you no longer create the producer method at all. |
Ah, understood. Yes, that would work. |
Technically, the |
To clarify, you're considering I was wondering because, assuming |
|
I quickly put together an implementation of |
This comment has been minimized.
This comment has been minimized.
@yrodiere I'm not asking if it's useful - we agreed on that while discussing #43765 ;-). I'm just saying that it's a "niche" feature. And the users that would understand this feauture would not need a new sophisticated API.
@Ladicek IIUC |
That is indeed correct, although not exactly friendly, I would say. It seems to me that it is way too soon to know how exactly users are going to use this feature and so too soon to know how we can improve it. I'll add the 2 methods you mention for now and we can revisit later. |
That sounds like a plan. We can always improve the UX later based on the feedback from users. |
614630b
to
3a1d883
Compare
Done. |
Status for workflow
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this is a good course of action for now.
Thank you @Ladicek!
Status for workflow
|
Related to #43765