-
1. Re: Undemanding Dependencies
alesj Jan 20, 2010 11:06 AM (in response to dmlloyd)I want to declare a relationship, A depending on B, where B is on-demand. However, I don't want A to cause B to start if nothing else depends on B. In other words, A should only start if something else causes B to start.
Is this possible?
Yes, but not declaratively, only programmatically.
This is how I would do it.
* declare both A, B as On_Demand
* install B --> ControllerContext --> DepenencyInfo
* once you have DependencyInfo --> add LifecycleCallbackItem (LCI)
* this LCI should simply enable (and install) A
-
2. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 12:09 PM (in response to alesj)In this case, what do you consider "-->" to mean? I'm producing a BeanMetaData but after that I don't have any control over how the beans are installed. I don't see any way to get a ControllerContext or DependencyInfo off of a BMD. I think I see what you're getting at (using a lifecycle callback on the parent to enable the child), I just don't see how to connect the dots. -
3. Re: Undemanding Dependencies
adrian.brock Jan 21, 2010 1:02 PM (in response to dmlloyd)I would say it should just be like any other circular dependency:
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" /></property>
<bean>
<bean name="B" mode="On Demand">
<demand targetState="Instantiated">A</demand>
</bean>
i.e. starting B triggers starting A which then gets injected with B.
However, the AbstractDemandMetaData$DemandDependencyItem
overrides resolve(Controller) and doesn't include the
enableOnDemand() processing.
So it won't work, although I think it should?
This alternative should work although it looks a bit funny/backwards. ;-)
<bean name="A" mode="On Demand"/>
<bean name="B" mode="On Demand">
<install bean="A" method="setB">
<parameter><this/></parameter>
</install>
</bean>
-
4. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 1:15 PM (in response to adrian.brock)The twist here is that A is installed sometime after B and cannot access B's metadata. Also there may be lots of As all installed at different times, each depending on B but not requiring it to start.
It seems like there should be another controller mode which means "automatic but does not demand dependencies". It's not really a circular dependency, in principle at least, as B doesn't know or care about its A dependencies really, other than in the regular dependency graph sense i.e. "I've started up, now all my dependents may start".
-
5. Re: Undemanding Dependencies
adrian.brock Jan 21, 2010 1:36 PM (in response to dmlloyd)Ok, then another way might be:
<bean name="A1" mode="On Demand">
<incallback property="b"/>
<bean>
<bean name="A2" mode="On Demand">
<incallback property="b"/>
<bean>
<bean name="B" mode="On Demand"/>
But the CallbackDependencyItem also overrides
resolve(Controller)
and so doesn't do the enableOnDemand()
What the above should do, is that when B gets
installed, all the beans that want an instance of that
class get enabled with their setB() method invoked.
-
6. Re: Undemanding Dependencies
adrian.brock Jan 21, 2010 1:44 PM (in response to dmlloyd)david.lloyd@jboss.com wrote:It seems like there should be another controller mode which means "automatic but does not demand dependencies". It's not really a circular dependency, in principle at least, as B doesn't know or care about its A dependencies really, other than in the regular dependency graph sense i.e. "I've started up, now all my dependents may start".
I don't know if it would be a new controller mode?
You mean something like:
<bean name="A" mode="On Demand Transitive">
<property name="b"><inject bean="B" /></property>
<bean>
<bean name="B" mode="On Demand"/>
Which would have the semantic of starting A when all its dependencies have started, i.e. B in this case. -
7. Re: Undemanding Dependencies
adrian.brock Jan 21, 2010 1:46 PM (in response to adrian.brock)Editor, ate my post again. ;-)
Following the last comment, I'm not sure you wouldn't want more fine grained control on
which dependencies start your bean?
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="true"/></property>
<bean>
<bean name="B" mode="On Demand"/>
-
8. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 1:47 PM (in response to adrian.brock)adrian@jboss.org wrote:
<bean name="A" mode="On Demand Transitive">
<property name="b"><inject bean="B" /></property>
<bean>
<bean name="B" mode="On Demand"/>
Which would have the semantic of starting A when all its dependencies have started, i.e. B in this case.Exactly.
-
9. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 1:49 PM (in response to adrian.brock)adrian@jboss.org wrote:
Editor, ate my post again. ;-)
Following the last comment, I'm not sure you wouldn't want more fine grained control on
which dependencies start your bean?
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="true"/></property>
<bean>
<bean name="B" mode="On Demand"/>
Ah, that would be neat. Let me see if I can wrap my brain around that...
So in this example, transitive-start would really mean that the targeted bean would control when this bean starts. So the question is, if you had two such injected bean properties, when would A start? When either injection is started, or only when both are?
-
10. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 1:57 PM (in response to adrian.brock)adrian@jboss.org wrote:
Ok, then another way might be:
<bean name="A1" mode="On Demand">
<incallback property="b"/>
<bean>
<bean name="A2" mode="On Demand">
<incallback property="b"/>
<bean>
<bean name="B" mode="On Demand"/>
But the CallbackDependencyItem also overrides
resolve(Controller)
and so doesn't do the enableOnDemand()
What the above should do, is that when B gets
installed, all the beans that want an instance of that
class get enabled with their setB() method invoked.
Replying to the first post last... perhaps I can work around this by creating a subclass of CallbackDependencyItem since I'm building this up programmatically anyway?
I might give that a go...
-
11. Re: Undemanding Dependencies
adrian.brock Jan 21, 2010 1:58 PM (in response to dmlloyd)david.lloyd@jboss.com wrote:
adrian@jboss.org wrote:
Editor, ate my post again. ;-)
Following the last comment, I'm not sure you wouldn't want more fine grained control on
which dependencies start your bean?
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="true"/></property>
<bean>
<bean name="B" mode="On Demand"/>
Ah, that would be neat. Let me see if I can wrap my brain around that...
So in this example, transitive-start would really mean that the targeted bean would control when this bean starts. So the question is, if you had two such injected bean properties, when would A start? When either injection is started, or only when both are?
You could make a configuration option, e.g. something like
Require both dependencies to start:
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="required"/></property>
<property name="c"><inject bean="C" transitive-start="required"/></property>
<bean>
Any one
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="optional"/></property>
<property name="c"><inject bean="C" transitive-start="optional"/></property>
<bean>
But unless starting A triggers some other knock-on effects, the second example is likely to stall with a missing dependency anyway. ;-)So I think you'd probably want all the dependencies marked transitive-start anyway?
-
12. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 2:15 PM (in response to dmlloyd)david.lloyd@jboss.com wrote:
What the above should do, is that when B gets
installed, all the beans that want an instance of that
class get enabled with their setB() method invoked.
Replying to the first post last... perhaps I can work around this by creating a subclass of CallbackDependencyItem since I'm building this up programmatically anyway?
I might give that a go...
Won't work - there can be many instances of B's class, so injecting by class isn't enough; it has to depend on a specific instance.
-
13. Re: Undemanding Dependencies
dmlloyd Jan 21, 2010 2:18 PM (in response to adrian.brock)adrian@jboss.org wrote:
david.lloyd@jboss.com wrote:
adrian@jboss.org wrote:
Editor, ate my post again. ;-)
Following the last comment, I'm not sure you wouldn't want more fine grained control on
which dependencies start your bean?
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="true"/></property>
<bean>
<bean name="B" mode="On Demand"/>
Ah, that would be neat. Let me see if I can wrap my brain around that...
So in this example, transitive-start would really mean that the targeted bean would control when this bean starts. So the question is, if you had two such injected bean properties, when would A start? When either injection is started, or only when both are?
You could make a configuration option, e.g. something like
Require both dependencies to start:
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="required"/></property>
<property name="c"><inject bean="C" transitive-start="required"/></property>
<bean>
Any one
<bean name="A" mode="On Demand">
<property name="b"><inject bean="B" transitive-start="optional"/></property>
<property name="c"><inject bean="C" transitive-start="optional"/></property>
<bean>
But unless starting A triggers some other knock-on effects, the second example is likely to stall with a missing dependency anyway. ;-)So I think you'd probably want all the dependencies marked transitive-start anyway?
The effect I'm envisioning for the latter case would run like this:
- Something ("D") depending on C is started
- This causes A to want to be demanded
- A then demands that B start, since A has been demanded
- A, B, and C are all started because D depended on C
Not sure if that really makes sense in terms of use case though. Also (disclaimer!) I'm not sure that I'm using the term "demand" correctly in this context.
-
14. Re: Undemanding Dependencies
alesj Jan 21, 2010 4:03 PM (in response to dmlloyd)In this case, what do you consider "-->" to mean?
A --> B, by this I mean that from A you can get a hold of B.I'm producing a BeanMetaData but after that I don't have any control over how the beans are installed. I don't see any way to get a ControllerContext or DependencyInfo off of a BMD. I think I see what you're getting at (using a lifecycle callback on the parent to enable the child), I just don't see how to connect the dots.
Even from BMD you have access to underlying ControllerContext, you just don't know it yet. :-)
It's the MetaDataVisitorNode methods, that get you that, we just need to properly override them.
BMD.initialVisit(MDVN node) <-- override this
ControllerContext context = node.getControllerContext();
DependencyInfo info = context.getDependencyInfo();
LifecycleCallbackItem item = new MyStarterLCI(); // this is what starts As
info.addLifecycleCallback(item);
Does this make more sense?