You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Yann Diorcet (JIRA)" <ji...@apache.org> on 2011/07/08 15:26:16 UTC

[jira] [Commented] (FELIX-3030) Bind/Unbind and lifecycle

    [ 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