[ 
https://issues.apache.org/jira/browse/FELIX-3030?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13061952#comment-13061952
 ] 

Yann Diorcet commented on FELIX-3030:
-------------------------------------

Hi,
We had a talk with Guillaume Sauthier about my problem and we have reached the 
conclusion that it is not a bug but more a lack of functionnality.

Take the following example:

I have a component (Abcd) that use many services (ServiceA) in order to 
register itself into them. This is an aggregate and optional dependency.
This component also requires another service(ServiceB) which is a mandatory 
dependency.

We want the following behaviour:
As long as my component is valid (a service of ServiceB type exists), my 
component is registered to all services of ServiceA type. Respectively, when 
the instance becomes invalid, I want to unregister my component from the 
service.
This behaviour is not so exotic, however it can't be reached without complexify 
the component code.
Indeed here is a solution: we added a flag that indicates if the instance is 
valid or not, then we keep this flag updated using the @Validate and 
@Invalidate methods. We must also manage registration / unregistration of the 
remaining services in @Validate / @Invalidate methods.

    @Component 
    @Instantiate 
    public final class Abcd { 
        @Requires 
        private ServiceB efg;
        
        private List<ServiceA> services = new LinkedList<ServiceA>();
        
        private boolean started = false; 

        @Validate 
        private void start() {
         for(ServiceA service: services)
         {
           service.register(this);
         }
         started = true; 
        } 

        @Invalidate 
        private void stop() {
         started = false;
         for(ServiceA service: services)
         {
           service.unregister(this);
         }
        } 

        @Bind(aggregate = true, optional = true) 
        private void bindServiceA(final ServiceA service) {
         services.add(service);
         if(started)
          {
            service.register(this);
          }
        } 
        @Unbind 
        private void unbindServiceA(final ServiceA service) {
          services.remove(service); 
          if(started)
          {
            service.unregister(this);
          }
        } 
    } 


It's not really user-friendly. Moreover, we had to duplicate the code handling 
registration/unregistration :'(
Finally, what we want is to have optional @Bind/Unbind methods to be only 
called when the instance is valid. That could be achieved by extending the 
dependency handler to support this feature.
>From a programming model POV, it could looks like the following (using 
>annotation):


    @Component 
    @Instantiate 
    public final class Abcd { 
        @Requires 
        private ServiceB efg;

        @Validate 
        private void start() {
        } 

        @Invalidate 
        private void stop() {
        } 

        @Bind(aggregate = true, optional = true, componentValidated = true) 
        private void bindServiceA(final ServiceA service) {
         service.register(this);
        } 
        @Unbind 
        private void unbindServiceA(final ServiceA service) {
         service.unregister(this);
        } 
    } 

Somehow each bind depends on the component state:
-The bind is done if the service is present AND if the component is valid
-The unbind is done if the service is no longer present OR if the component 
becomes invalid

WDYT ?

Thanks

> Bind/Unbind and lifecycle
> -------------------------
>
>                 Key: FELIX-3030
>                 URL: https://issues.apache.org/jira/browse/FELIX-3030
>             Project: Felix
>          Issue Type: Bug
>          Components: iPOJO
>    Affects Versions: iPOJO-1.8.0
>            Reporter: Yann Diorcet
>
> According to my 
> post(http://old.nabble.com/iPojo-lifecycle-and-dependencies-p32003301.html).
> It seems that there is a problem with the lifecycle and dependencies.
> @Component
> @Instantiate
> public final class Abcd {
>     @Requires
>     private Efg efg;
>     @Validate
>     private void start() {
>     }
>     @Invalidate
>     private void stop() {
>     }
>     @Bind(aggregate = true, optional = true)
>     private void bindXyz(final Xyz service) {
>     }
>     @Unbind
>     private void unbindXyz(final Xyz service) {
>     }
> }
> Scenario 1:
> -A new service(Efg1) provides Efg
> -A new service(Xyz1) provides Xyz 
> -The component Abcd is instantiated
> -The bind() is called with Xyz1
> -The start() of the component is called
> -The Efg1 is unregistered
> -The component is invalidated (Efg1 is gone) stop() is called
> -During the time that my component is invalidated, if a new Xyz service(Xyz2) 
> is registred (from an another bundle for example) bindXyz() is called
> -After that, if i stop my bundle, my component will be stopped but 
> unbindXyz() will be not called(neither for Xyz1 nor Xyz2).
> Scenario 2:
> -A new service(Efg1) provides Efg
> -A new service(Xyz1) provides Xyz 
> -The component Abcd is instantiated
> -The bind() is called with Xyz1
> -The start() of the component is called
> -The Efg1 is unregistered
> -The component is invalidated (Efg1 is gone) stop() is called
> -A new service(Efg2) provides Efg
> -The start() of the component is called
> Why all the already existing services are bound at the creation of the 
> component and not unbound at the "destruction" of the component?
> Another solution: Why don't bind the optional services at the validation of 
> the component and unbind them at the invalidation (like it seems to be done 
> with not optional service)?

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to