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