[ 
https://issues.apache.org/jira/browse/FELIX-4913?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Pierre De Rop resolved FELIX-4913.
----------------------------------
    Resolution: Fixed

> DM Optional callbacks may sometimes be invoked twice
> ----------------------------------------------------
>
>                 Key: FELIX-4913
>                 URL: https://issues.apache.org/jira/browse/FELIX-4913
>             Project: Felix
>          Issue Type: Bug
>          Components: Dependency Manager
>    Affects Versions: org.apache.felix.dependencymanager-r3
>            Reporter: Pierre De Rop
>            Assignee: Pierre De Rop
>             Fix For: org.apache.felix.dependencymanager-r4
>
>
> The following use case is not currently supported by the DM state machine, 
> which suffers from a bug where sometimes, when the use case happens, the same 
> optional callback may be invoked twice.
> The following case is supported by DS, so DM should support it, regardless of 
> the fact that the design of this use case is arguable/questionable:
> - there is a component B
> - there is a component BFactory (registered in the OSGI registry). And 
> BFactory.createB() creates a B instance and simply registers it in the OSGi 
> registry.
> - there is a A component that has two OPTIONAL dependencies:
> {code}
>   A.bind(BFactory)
>   A.bind(B b)
> {code}
> - Then A is created and is starting. Since BFactory is available, the DM 
> state machine for A transits from the INSTANTIATED_AND_WAITING_FOR_REQUIRED 
> into the  TRACKING_OPTIONAL state:
> {code}
>         if (oldState == ComponentState.INSTANTIATED_AND_WAITING_FOR_REQUIRED 
> && newState == ComponentState.TRACKING_OPTIONAL) {
>             invokeAutoConfigInstanceBoundDependencies();
>             invokeAddRequiredInstanceBoundDependencies();
>             invoke(m_callbackStart);
>             invokeAddOptionalDependencies();
>             registerService();
>             notifyListeners(newState);
>             return true;
>         }
> {code}
> - then, when the invokeAddOptionalDependencies() is running, it is invoking 
> A.bind(BFactory b). At this exact point, the A.bind(BFactory) method calls 
> bf.createB():
> {code}
> A.bind(BFactory bf) {
>     bf.createB();
> }
> {code}
> - this has the following side effect: a B service is synchronously registered 
> in the OSGI service registry. So ComponentImpl.handleAdded() is called, and 
> since we are in the
> TRACKING_OPTIONAL state (we are entering into this state), then the A.bindB(B 
> b) callback is invoked.
> - BUT ... we are still running in the invokeAddOptionalDependencies() method. 
> So when that method is about to iterate on the available services of the B 
> dependency, then it calls a
> second time the "A.bind(B)" callback.
> I have a patch for this use case, which I have extensively tested since two 
> days.
> To preserve my soul, the patch is simple and conservative: I use the same 
> technique that was done in the ConfigurationDependencyImpl class: I'm using a 
> cache of callbacks that ensures that the same callback won't be invoked more 
> than one time. The advantage of this patch is that it does not make too much 
> polutions in the state machine which is not altered too much.
> I will also commit a test case which demonstrates the issue.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to