1 2 Previous Next 16 Replies Latest reply on Jan 22, 2010 3:27 AM by Ales Justin

    Undemanding Dependencies

    David Lloyd Master

      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?

        • 1. Re: Undemanding Dependencies
          Ales Justin Master
          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
            David Lloyd Master
            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 Master

              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
                David Lloyd Master

                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 Master

                  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 Master
                    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 Master

                      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
                        David Lloyd Master

                        adrian@jboss.org wrote:

                         

                        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.

                        Exactly.

                        • 9. Re: Undemanding Dependencies
                          David Lloyd Master

                          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
                            David Lloyd Master

                            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 Master

                              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
                                David Lloyd Master

                                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
                                  David Lloyd Master

                                  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:

                                  1. Something ("D") depending on C is started
                                  2. This causes A to want to be demanded
                                  3. A then demands that B start, since A has been demanded
                                  4. 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
                                    Ales Justin Master
                                    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?

                                    1 2 Previous Next