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.