felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Clement Escoffier <clement.escoff...@gmail.com>
Subject Re: A couple of questions regarding iPojo interceptors
Date Mon, 03 Mar 2014 15:14:48 GMT

On 3 mars 2014, at 15:53, Bengt Rodehav <bengt@rodehav.com> wrote:

> OK - I now understand what you mean. It seems that the design is supposed
> to do what I expected then. We think alike :-)

Yes… Theoretically it should be like that….  

> 
> 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 <clement.escoffier@gmail.com>:
> 
>> 
>> On 3 mars 2014, at 15:18, Bengt Rodehav <bengt@rodehav.com> 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 <
>> clement.escoffier@gmail.com>:
>>> 
>>>> Hi,
>>>> 
>>>> On 3 mars 2014, at 13:14, Bengt Rodehav <bengt@rodehav.com> 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 <
>> clement.escoffier@gmail.com
>>>>> :
>>>>> 
>>>>>> 
>>>>>> On 21 févr. 2014, at 14:15, Bengt Rodehav <bengt@rodehav.com>
wrote:
>>>>>> 
>>>>>>> Hello Clement,
>>>>>>> 
>>>>>>> Some comments inline below.
>>>>>>> 
>>>>>>> /Bengt
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 2014-02-21 12:53 GMT+01:00 Clement Escoffier <
>>>>>> clement.escoffier@gmail.com>:
>>>>>>> 
>>>>>>>> Hi,
>>>>>>>> 
>>>>>>>> On 20 févr. 2014, at 13:22, Bengt Rodehav <bengt@rodehav.com>
>> 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: users-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>> 
>>>>>> 
>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>> 
>>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Mime
View raw message