I think you can take a look at what aries blueprint does for these cases.
They create a proxy for each injected service and switch the service if
the original one goes away. If no service is available then I think it
waits for some time for a new one to come and throws an exception if a
time out happens.
Perhaps a similar behaviour can also be added for DS. Not sure if it
matches the DS ideas though.
Christian
On 13.09.2013 12:10, Thomas Diesler wrote:
Thank you all for your replies. We ended up with three measures
#1 assert that the component is still valid on entry of every public
method (AtomicBoolean set by activate/deactivate)
#2 Use a ValidatingReference
<https://github.com/tdiesler/jbosgi/blob/master/testsuite/functional/src/main/java/org/jboss/test/osgi/ds/support/ValidatingReference.java> to
hold unary references to dependent services (prevents NPE when a
dependent service goes away)
#3 Throw an InvalidComponentException runtime exception on #1 and #2
The idea is that access to a deactivated reference never throws NPE
Access to the public API is prevented from deactivated service instances
cheers
--thomas
On Sep 11, 2013, at 11:11 AM, Richard S. Hall <[email protected]
<mailto:[email protected]>> wrote:
Resending my reply from yesterday since my original message didn't
seem to go through...
----
Yes, you can do some of these sorts of things with iPOJO.
First, iPOJO has the notion of a service-level service dependency as
well as an implementation-level service dependency (which is the
level of DS dependencies). Second, iPOJO caches services references
within a service method invocation so that a thread calling a method
on a service will see the same injected services until the thread
exits the invoked service method.
It doesn't deal with configuration locking (at least not of which I
am aware).
-> richard
On 9/10/13 06:41 , Thomas Diesler wrote:
Hi Folks,
in Fabric we have a service model whereby services have
interdependencies, are configurable and dynamic by nature - all of
which is managed in OSGi with the help of Declarative Services. To
illustrate I use a simple example
ServiceT {
@Reference
ServiceA serviceA;
@Reference
ServiceB serviceB;
public doStuff() {
// that uses serviceA & serviceB
}
}
The injection is handled by the DS framework - there are various
callbacks involved.
Lets assume the system is fully configured and a client makes a call
on ServiceT
ServiceT serviceT = getServiceT();
serviceT.doStuff();
Due to the dynamic nature of OSGi services and their respective
configuration ServiceT must deal with the following possible/likely
situations
#1 An instance of a referenced service is not available at the point
of access (i.e. serviceA is null)
#2 In the context of a single call the service instance may change
(i.e. call may span multiple instances of serviceA)
#3 In the context of a single call the configuration of a service
instance may change (i.e. serviceA is not immutable, sequential
operations on A may access different configurations)
In OSGi there is no notion of global lock for service/configurations
nor a notion of lock of a given set of services/configurations - I
cannot do
lock(T, A, B);
try {
ServiceT serviceT = getServiceT();
serviceT.doStuff();
} finally {
unlock(T, A, B);
}
This code is also flawed because it assumes that the caller of
doStuff() is aware of the transitive set of services involved in the
call and that this set will not change.
As a conclusion we can say that the behaviour of doStuff() is only
defined when we assume stability in service availability and their
respective configuration, which happens to be true most of the time
- nevertheless, there are no guarantees for defined behaviour.
How about this ...
The functionality of A and B and its respective configuration is
decoupled from OSGi and its dynamicity
A {
final Map config;
public doStuffInA() {
}
}
B {
final Map config;
public doStuffInB() {
}
}
ServiceA and ServiceB are providers of immutable instances of A and
B respectively. There is a notion of CallContext that provides an
idempotent set of instances involved in the call.
CallContext {
public T get(Class<T> type);
}
This guarantees that throughout the duration of a call we always
access the same instance, which itself is immutable. CallContext
also takes care of instance availability and may have appropriate
timeouts if a given instance type cannot be provided. It would still
be the responsibility of A/B to decide wether an operation is
permissible on stale configuration.
Changes to the system would be non-trival and before I do any
prototyping I'd like to hear what you think.
cheers
--thomas
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected] <mailto:[email protected]>
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
http://www.talend.com
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev