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

Marcel Offermans closed FELIX-1546.
-----------------------------------


Part of the 3.0.0 release.

> DM/Temporal Dependency/Bound Service Replacement features
> ---------------------------------------------------------
>
>                 Key: FELIX-1546
>                 URL: https://issues.apache.org/jira/browse/FELIX-1546
>             Project: Felix
>          Issue Type: New Feature
>          Components: Dependency Manager
>            Reporter: Pierre De Rop
>            Assignee: Marcel Offermans
>            Priority: Minor
>         Attachments: DM-1.tgz, DM-2-test.tgz, DM-2.tgz, DM-3.tgz, DM-4.tgz, 
> DM-test.tgz, DM.tgz
>
>
> This issue proposes some new features for DM:
> Feature 1): dealing with service dynamics: Temporal dependencies
> ----------------------------------------------------------------
>    
> So far, with DM, when a service looses one of its required dependencies, the 
> service is
> deactivated. For stateless required dependencies, it would then be nice to 
> support a temporal
> required dependency, which blocks the caller thread while the dependency is 
> being updated.
> In the attached DM.tgz patch, you will find a new 
> "TemporalServiceDependency.java" class, which extends the
> "ServiceDependency" class. In TemporalServiceDependency.java, you'll find a 
> setTimeout method
> which takes a timeout parameter, in millis, specifying  the max time to wait 
> (30 seconds by
> default). After timeout, an unchecked "ServiceUnavailableException" is fired 
> to the caller
> thread. 
> Here is a more specific description of what the new 
> "TemporalServiceDependency" class is doing
> exactly: 
> The class actually uses a Dynamic Proxy which wraps the actual service 
> dependency
> instance. When the service is lost, we check if there is an available 
> replacement service from the  
> tracker. If true, then we just update our internal service with the new one. 
> If false, then we set
> a flag, which blocks any thread that invokes the service through the Dynamic 
> Proxy. On timeout,
> we raise an unchecked ServiceUnavailableException, telling that the required 
> service is unavailable (but we
> don't deactivate the service). The next time the dependency is invoked and if 
> the service has come
> up, then the method will invoke the new service transparently.
> Using setTimeout(0) is supported: The thread won't be blocked, but will catch 
> the unchecked
> exception immediately, in case of service loss.
> Of course, I don't pretend here to propose a feature as powerful as iPOJO 
> "temporal dependencies"
> or Blueprint specification.  However, you will see that the proposed patch is 
> somewhat
> lightweight and is just fine for Dependency Manager. 
> For example, Here is an example ->
> dm.add(createService()
>        .setImplementation(Client.class)
>        .add(createTemporalServiceDependency()
>           .setService(MyService.class) // AutoConfig
>           .setTimeout(5000)));
> public class Client implements Runnable {
>   private Thread _thread;
>   private MyService _service; // Dynamic Proxy auto injected (AUTO CONFIG 
> MODE)
>   void start() {
>     _thread = new Thread(this);
>     _thread.start();
>   }
>   public void run() {
>     while (true) {
>       try { 
>         _service.doService(); // will block while myService is updated
>       } catch (Throwable t) {
>         t.printStackTrace(); // ServiceUnavailableException if the service is 
> not here for more than 5 seconds
>       }
>     }
>   }
> }
> One last note: this feature is only meaningful for stateless services, not 
> for sateful
> services. But for stateless services, I think that it is cool to not 
> re-activate the whole
> service while the dependency is updated. For stateful services, I don't think 
> that temporal
> dependencies applies because we would then loose service internal states 
> between updates ...
> One last note: in TemporalServiceDependency, I override returned type which 
> is only supported in
> jdk 1.5.
> For instance, the TemporalServiceDependency.setTimeout is defined as this:
>   public TemporalServiceDependency setTimeout( long timeout ) { ...}
> So, I am wondering if that would be possible to impose jdk 1.5 for the next 
> version of DM ?
> Feature 2): dealing with Bound Service Replacement:
> ---------------------------------------------------
> We would like DM to be able to replace a lost required dependency, by another 
> existing one (if
> available from the registry), but without deactivating the service. 
> Currently, the service is
> deactivated when loosing one of its required dependencies. If, however, a 
> replacement is
> available from tracker, we just would like invoke the "changed" service 
> callback (instead of
> deactivating it).
> I know that in DeclarativeService, the "added", then the "removed" callback 
> would be invoked, but
> I think It's much more intuitive to invoke the "changed" callback.
> For example, when a required service dependency is lost, DM could behave like 
> the following: 
> 1- lookup another service (which matches the lost service dependency filter).
> 2- If found, update the service (in AutoConfig mode), or invoke a "changed" 
> callbacks.
> 3- Otherwise, if AutoConfig is turned off and there is no "changed" callback, 
> then deactivate the
>    service (like it is the case currently). 
> The fix in located in the ServiceDependency.java (see removedService method).
> Notice that I also changed the makeUnavailable method.
> Feature 3): let the DM shell display service dependencies filters.
> -----------------------------------------------------------------------------
> Currently, the DM shell displays the service dependencies without the service 
> filter. So that is
> problematic when a service have multiple dependencies on the same service, 
> but with different
> filters.
> For example: when typing the command "dm", the patch is now displaying the 
> following:
> [7] test.dm
>     class test.Client registered
>       test.Printer(color=true) service required available
>       test.Printer(color=false) service required available
> The fix is located in ServiceDependency.java, in the getName() method, which 
> appends the service
> filter after the service name. Notice that we don't display the 'objectClass' 
> parameter.
> Auto Configuration vs Callbacks
> -------------------------------
> Well this is not a feature, but rather an improvement regarding the issue 
> https://issues.apache.org/jira/browse/FELIX-1278
> Recently, you fixed the issue FELIX-1278, where we asked to turn off autoconf 
> when setCallbacks is invoked 
> (thank you for the fix !).
> However, I think we forgot to ask you to not turn off autoconfig if both 
> setCallback /
> setAutoConfig(true) are invoked. Indeed, in some times, it may make sense to 
> use both methods, 
> like this: ->
>    dm.add(createServiceDependency()
>         .setService(MyService.class)
>         .setRequired(false)
>         .setAutoConfig("_field") 
>         .setCallbacks("add", "remove"));
> Here, we inject an optional configuration in AutoConfig mode (field 
> injection), but we also
> provide a callback method to be able to handle new services (after 
> activation).
> You could tell me that with the current svn fix, we could invoke setCallbacks 
> BEFORE
> setAutoConfig. But I just added a flag when
> setAutoConfig method is called explicitly (in order to avoid turning off auto 
> config from
> setCallbacks method). The fix in located in ServideDependency.java
> Regards;
> /pierre

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

Reply via email to