I now added logging to the following methods: - onServiceArrival - onServiceDeparture - onServiceModified
I tried starting both with a clean start and then without clean. I got the following results: *bin\karaf.bat clean* accept: intercepted onServiceArrival: 1 matching references getServiceReferences accept: intercepted *bin\karaf.bat* accept: intercepted configurationChanged invalidating... Invalidating matching... accept: intercepted Invalidating selected... Done invalidating Validated getServiceReferences Invalidated As you can see the instance never becomes valid on a clean start. Then again, no configuration changes are detected on a clean start. It seems to be when I detect a configuration change and manually invalidate the dependencies that the problem appears. Does this give you any clue? /Bengt 2014-03-03 15:53 GMT+01:00 Bengt Rodehav <[email protected]>: > OK - I now understand what you mean. It seems that the design is supposed > to do what I expected then. We think alike :-) > > I'll add some more tracing as you suggested and then get back to you. > > /Bengt > > > 2014-03-03 15:46 GMT+01:00 Clement Escoffier <[email protected]> > : > > >> On 3 mars 2014, at 15:18, Bengt Rodehav <[email protected]> wrote: >> >> > Hi Clement, >> > >> > Yes, I use the filter to make sure that the instance does not become >> valid >> > until it has been intercepted - that part seems to work. However, in my >> > case, the instance become valid AFTER my accept() method has been called >> > but BEFORE my getServiceReferences() method has been called. This is >> > causing my problems. >> > >> > I'm a little curious regarding your wording: >> > >> > "A (mandatory) dependency becomes valid only if the selected service >> set is >> > not empty. In other words, all your interceptors should have been called >> > before deciding to set the dependency state to valid." >> > >> > I don't see how the first sentence has anything to do with the second >> > sentence. >> >> This is how iPOJO resolves services. It first considers the services from >> the service registry (called base service set). This set is processed by >> tracking interceptor (such as LDAP filter...) to get a matching service set. >> Then, a ranking interceptor is called to sort the set, and to get the >> selected service set. A mandatory service dependency cannot be valid if >> this last set is empty (in theory). That means that both accept and >> getServiceReferences should have been called to determine whether or not >> the dependency is valid. The accept method is called to build the matching >> service set, while getServiceReferences is called to retrieve the selected >> service set. >> >> > >> > I have a dependency declared as follows: >> > >> > @Requires(optional = false, id = "extenders", filter = >> > "(intercepted=true)") >> > private IRouteExtender[] mExtenders; >> > >> > Thus it is mandatory. Also, there are services of type IRouteExtender >> > registered so that part is resolved. But until the accept() method has >> been >> > called the "(intercepted=true)" part is not satisfied. When my accept() >> > method has been called the "(intercepted=true)" part becomes satisfied >> and >> > my instance becomes valid right away instead of waiting for the result >> of >> > the getServiceReferences() method. This is the problem because in my >> > getServiceReferences() method I evalutate the matching dependencies (by >> > looking at a property) and determine that they are not valid. I >> therefore >> > return an empty set of matching service references and the instance now >> > becomes invalid. >> > >> > I do not think it should be possible to validate an instance "in the >> midst >> > of intercepting" as is the case for me. I must be completely done >> > intercepting first. >> >> That should not be the case. Definitely a bug.... The dependency state >> should not be re-evaluated before having notified the ranking interceptor. >> >> So far, you are implementing only getServiceReferences, can you implement >> and add traces in onServiceArrival ? >> >> Clement >> >> >> >> > >> > /Bengt >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > >> > 2014-03-03 13:51 GMT+01:00 Clement Escoffier < >> [email protected]>: >> > >> >> Hi, >> >> >> >> On 3 mars 2014, at 13:14, Bengt Rodehav <[email protected]> wrote: >> >> >> >>> Hello again Clement! >> >>> >> >>> Skiing trip is now over - time to get back to the interceptors... >> >>> >> >>> Regarding your questions in the last post: Yes, I only add a property >> on >> >>> the chosen service reference (intercepted is set to true), I do not >> >> change >> >>> the filter. >> >>> >> >>> I have tested the theory regarding config admin / file install and it >> is >> >>> not the problem. >> >>> >> >>> It seems to me that there is no guarantee that both accept() and the >> >>> getServiceReferences() are both called before an instance becomes >> valid. >> >> I >> >>> haven't looked at the source code in detail yet but is the design such >> >> that >> >>> this is not supposed to be possible or am I requesting a new feature? >> In >> >>> other words, have I found a bug or not? >> >>> >> >>> Ideally I think it should work as follows: >> >>> >> >>> - When in "interceptor mode" the state of the instance should not >> change >> >>> until all the interceptors (and all callbacks of the interceptors) >> have >> >>> taken effect. >> >>> >> >>> - Initially then instance should not become valid until all the >> >>> interceptors (and all callbacks of the interceptors) have taken >> effect. >> >>> >> >>> With "interceptor mode" I mean that something has triggered iPojo to >> >> begin >> >>> calling the registered interceptors. >> >>> >> >>> Not sure if this is in accordance with your design. How is it >> supposed to >> >>> work? >> >> >> >> >> >> It might be a bug and a new feature. >> >> >> >> I designed interceptors to be highly dynamic, so can come and leave at >> >> anytime, and without having the components aware of them. That's why >> >> service dependencies do not know which interceptors handle them. >> >> Unfortunately, this design has some trade-off / drawbacks. If your >> instance >> >> starts before the interceptors, it might be valid for a little amount >> of >> >> time, until the interceptors handle the dependency. However in your >> case >> >> you have a filter on the dependency that should avoid this case. >> >> >> >> If you still have this filter, it is definitely a bug. A (mandatory) >> >> dependency becomes valid only if the selected service set is not >> empty. In >> >> other words, all your interceptors should have been called before >> deciding >> >> to set the dependency state to valid. >> >> >> >> About the feature, I start thinking that the independence between the >> >> interceptor and the dependencies may be problematic. For instance, I've >> >> another use case where they implement a new handler (an extension of >> the >> >> dependency handler) to ensure the availability of one specific >> interceptor. >> >> The dependency is invalid until the interceptor arrives. >> >> >> >> Clement >> >> >> >>> >> >>> /Bengt >> >>> >> >>> >> >>> >> >>> >> >>> 2014-02-24 8:17 GMT+01:00 Clement Escoffier < >> [email protected] >> >>> : >> >>> >> >>>> >> >>>> On 21 févr. 2014, at 14:15, Bengt Rodehav <[email protected]> wrote: >> >>>> >> >>>>> Hello Clement, >> >>>>> >> >>>>> Some comments inline below. >> >>>>> >> >>>>> /Bengt >> >>>>> >> >>>>> >> >>>>> >> >>>>> 2014-02-21 12:53 GMT+01:00 Clement Escoffier < >> >>>> [email protected]>: >> >>>>> >> >>>>>> Hi, >> >>>>>> >> >>>>>> On 20 févr. 2014, at 13:22, Bengt Rodehav <[email protected]> >> wrote: >> >>>>>> >> >>>>>>> This is a follow up on another discussion I had with Clement on >> this >> >>>>>>> mailing list: >> >>>>>>> >> >>>>>>> >> >>>>>> >> >>>> >> >> >> http://apache-felix.18485.x6.nabble.com/Using-iPojo-interceptors-tt5006168.html#a5006276 >> >>>>>>> >> >>>>>>> I'm now trying to get the interceptor solution into production. >> >>>>>>> >> >>>>>>> Remember that I have to invalidate my instances when their >> >>>> configuration >> >>>>>> is >> >>>>>>> changed. This is because I need to re-evalutate the dependencies >> for >> >>>> the >> >>>>>>> instance. >> >>>>>>> >> >>>>>>> Originally, I only called the invalidateSelectedServices() method >> on >> >>>> the >> >>>>>>> DependencyModel. This worked mostly but not when starting a fresh >> >>>>>> container >> >>>>>>> (I use Karaf and start it with "bin\karaf.bat clean"). My instance >> >> then >> >>>>>>> first becomes valid but then becomes invalid. I think this is >> because >> >>>> of >> >>>>>>> the ordering. The accept() method had not been called prior to >> >>>>>>> the getServiceReferences() method. The dependency is therefore not >> >> set >> >>>> to >> >>>>>>> "intercepted=true" which makes it invalid. >> >>>>>> >> >>>>>> the filter is updated by the interceptor. (just want to be sure I >> >>>>>> understand). In that case, if the interceptor arrives after the >> >> instance >> >>>>>> creation, the filter will be set when the interceptor arrives. >> >>>>>> >> >>>>> >> >>>>> Yes, my interceptor sets intercepted to true on the dependency which >> >>>> makes >> >>>>> sure that the filter match. >> >>>> >> >>>> So the filter is not modified by the interceptor, it just add a new >> >>>> property on the chosen service reference to match the filter. >> >>>> >> >>>>> >> >>>>> >> >>>>> >> >>>>>> >> >>>>>>> >> >>>>>>> Replacing the call to invalidateSelectedServices() with a call to >> >>>>>>> invalidateMatchingServices() seems to do the trick. However, >> there is >> >>>> one >> >>>>>>> small glitch that I would like to fix. >> >>>>>>> >> >>>>>>> If I have a configuration that should not be valid (e g I >> specified >> >> an >> >>>>>>> extender id that is not present) the instance should never be >> valid. >> >>>> But, >> >>>>>>> when starting Karaf (both with "bin\karaf.bat" and "bin\karaf.bat >> >>>>>> clean"), >> >>>>>>> the instance becomes valid before it becomes invalid. It does end >> up >> >> in >> >>>>>> the >> >>>>>>> right state (invalid in this case) but for a short period of time >> it >> >> is >> >>>>>>> valid which will cause a lot of things to happen in my code that >> then >> >>>>>> must >> >>>>>>> be reversed when it becomes invalid. >> >>>>>>> >> >>>>>>> I logged the sequence of events and it seems that the accept() >> method >> >>>> is >> >>>>>>> called first. I will then set "intercepted=true". This immediately >> >>>> makes >> >>>>>>> the instance valid. Shortly thereafter getServiceReferences() is >> >>>> called. >> >>>>>> I >> >>>>>>> will then re-calculate the dependency requirements and when I >> later >> >>>>>>> invalidate the dependencies the instance will become valid. >> >>>>>>> >> >>>>>>> So, there is a short time frame where the instance is valid >> although >> >> it >> >>>>>>> shouldn't be. How can I fix that? >> >>>>>> >> >>>>>> This looks like a bug, as the dependency can be valid only if the >> set >> >> of >> >>>>>> selected services is not empty. From what you say, it looks like >> the >> >>>>>> dependency is valid because the set of matching services is not >> empty. >> >>>>>> >> >>>>> >> >>>>> Is there anything I can do to investigate this? Is it possible for >> you >> >> to >> >>>>> take a look if there is indeed a "gap" where this can happen? >> >>>> >> >>>> My first guess would be in the ServiceReferenceManager coordinating >> the >> >>>> interceptors. >> >>>> >> >>>>> >> >>>>> I think that things are a little complicated since I also listen on >> >>>>> configuration changes. I need to recalculate the matching services >> when >> >>>> the >> >>>>> configuration of the intercepted instance changes. When starting the >> >>>>> container (Karaf), I get more than one configuration change and thus >> >> the >> >>>>> dependencies are invalidated more than once. What if the sequence >> were: >> >>>>> >> >>>>> 1. Configuration change causing the dependencies to become >> invalidated >> >>>>> 2. Accept. Will set intercepted to true >> >>>>> 3. getServiceReferences which will calculate the required >> dependencies >> >>>>> 4. Configuration change again causing the dependencies to become >> >>>> invalidated >> >>>>> 5. Accept. Will set intercepted to true >> >>>>> 6. getServiceReferences which will calculate the required >> dependencies >> >>>>> >> >>>>> Not sure if there is any point in which an instance could become >> valid >> >>>> when >> >>>>> it shouldn't. >> >>>>> >> >>>>> I will also try to see if the problem could be the configuration >> >> admin. I >> >>>>> use file install for my configuration. I have a feeling that the >> first >> >>>>> configuration being pushed is a default configuration and not the >> one >> >>>> from >> >>>>> the configuration file. Then that might explain it. >> >>>>> >> >>>> >> >>>> Oh, that's an interesting hint. That's definitely possible. >> >>>> >> >>>> Enjoy your vacations, mine are over.... >> >>>> >> >>>> >> >>>> Regards, >> >>>> >> >>>> Clement >> >>>> >> >>>>> >> >>>>>>> >> >>>>>>> From my point of view this is similar to a transaction. I do not >> want >> >>>> the >> >>>>>>> instance to become valid before I have done all my "intercepting" >> >> which >> >>>>>> is >> >>>>>>> after BOTH the accept() method AND the getServiceReferences() >> method >> >>>> have >> >>>>>>> been called. >> >>>>>> >> >>>>>> In theory, it is how it should work... >> >>>>>> >> >>>>>>> >> >>>>>>> BTW I also noted that the "dependencies" member in >> >>>>>>> the DefaultDependencyInterceptor class (I extend the >> >>>>>>> DefaultServiceRankingInterceptor class) seems to contain >> duplicates >> >> of >> >>>> my >> >>>>>>> dependency. The same DependencyModel instance occurs twice in the >> >> List. >> >>>>>>> Seems like a bug to me. Perhaps the List should be a Set? >> >>>>>> >> >>>>>> Definitely, could you open an issue ? >> >>>>>> >> >>>>>> Clement >> >>>>>> >> >>>>>>> >> >>>>>>> /Bengt >> >>>>>> >> >>>>>> >> >>>>>> >> --------------------------------------------------------------------- >> >>>>>> To unsubscribe, e-mail: [email protected] >> >>>>>> For additional commands, e-mail: [email protected] >> >>>> >> >>>> >> >> >> >> >> >> --------------------------------------------------------------------- >> >> To unsubscribe, e-mail: [email protected] >> >> For additional commands, e-mail: [email protected] >> >> >> >> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> For additional commands, e-mail: [email protected] >> >> >

