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 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]> 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]
> https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to