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
            Priority: Minor
         Attachments: 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.
-
You can reply to this email to add a comment to the issue online.

Reply via email to