Re: [osgi-dev] Dealing with bouncing

2018-07-23 Thread Tim Ward via osgi-dev
An alternative way to look at this is simply that your DS component needs to be 
sufficiently thread-safe to deal with the consequences of its own internal 
threading model. In this case:

> What would be a good (and simple) strategy to handle this type of 
> long-running configuration, where the configuration is in a different thread 
> and depends on services that may come and go?

Long-running asynchronous activation isn’t where DS really shines for several 
reasons:

There’s no way to tell DS that your component activation is asynchronous. Once 
the activate method returns then DS will give your object to the client bundle. 
As you’ve already discovered, Promises can make this much simpler to deal with.
As you’ve seen, the DS “happens before” model is based on when your activate 
method returns. Once you go into another thread you have to deal with the 
consequences of that
If your long-running activation fails, then it’s too late to tell DS that the 
component is broken. To be safe here you really need to disable your component 
on failure.

That said, it is perfectly possible to activate asynchronously in a safe way. 
It’s just very important to signal to any thread(s) that you started that they 
need to stop and abandon their work. Thread.interrupt() is useful here, as is 
having an AtomicBoolean flag in your component that you set to false during 
deactivation. These states should be checked regularly during startup, and the 
“startup thread" should be prepared to abandon any work it has done if/when it 
has become invalid.

Best Regards,

Tim

> On 23 Jul 2018, at 08:00, Peter Kriens via osgi-dev  
> wrote:
> 
> 
> 
> Ok … on the top of my head …
> 
> 
>   public interface Bar {
>   void m1();
>   void m2();
>   }
> 
>   @Component 
>   public class BarImpl implements Bar {
>   Deferred   delegate = new Deferred<>();
> 
>   @Reference
>   void setExec( Executor e ) {
>   delegate.resolve( new BarImpl2(e) );
>   }
> 
> 
>   public void m1() {
>   delegate.getPromise().m1();
>   }   
> 
>   public void m2() {
>   delegate.getPromise().m2();
>   }   
>   }
> 
> This works for you?
> 
> Kind regards,
> 
>   Peter Kriens
> 
> 
>   
>> On 22 Jul 2018, at 22:51, David Leangen via osgi-dev 
>>  wrote:
>> 
>> 
>> Hi Peter,
>> 
>> Thanks for the tip.
>> 
>> I’m not quite getting it. Would you be able to direct me to an example?
>> 
>> Thanks!
>> =David
>> 
>> 
>> 
>>> On Jul 22, 2018, at 21:49, Peter Kriens  wrote:
>>> 
>>> In some cases (when the extra complexity was warranted) I let the component 
>>> class act as a proxy to a delegate. I then get the delegate from a  
>>> Promise. So you just forward every method in your service interface to the 
>>> delegate. There is a function in Eclipse that will create the delegation 
>>> methods.
>>> 
>>> In general you want to afford this complexity and for example use a simple 
>>> init() method that blocks until init is done. However, the delegate has 
>>> some nice qualities if you switch more often than just at init.
>>> 
>>> Kind regards,
>>> 
>>> Peter Kriens
>>> 
 On 22 Jul 2018, at 10:35, David Leangen via osgi-dev 
  wrote:
 
 
 Hi,
 
 This may be more of a basic Java question, but I’ll ask it anyway because 
 it relates to “bouncing” and the handling of dynamic behavior.
 
 In my @Activate method, I configure my component. Since the configuration 
 may be long-running (data is retrieved remotely), I use a Promise. But, 
 the component is available before it is actually “ready”. So far, this has 
 not been a problem.
 
 It looks something like this:
 
 @Reference private Store dataStore;
 
 @Activate
 void activate() {
 configure(dataStore);
 }
 
 void configure(Store withDataStore) {
 // Configuration is set up via a Promise, using a data store to retrieve 
 the data
 }
 
 However, because there is some bouncing occurring, I think what is 
 happening is that configure() starts running in a different thread, but in 
 the meantime the reference to the dataStore is changed. The error log 
 shows that the data store is in an impossible state. After following a 
 hunch, I could confirm that the configureData process is running on a data 
 store service that was deactivated during bouncing.
 
 What would be a good (and simple) strategy to handle this type of 
 long-running configuration, where the configuration is in a different 
 thread and depends on services that may come and go?
 
 
 Note: in the end, the component gets configured and the application runs, 
 but I would still like to be able to handle this situation properly.
 
 
 Thanks!
 

Re: [osgi-dev] Dealing with bouncing

2018-07-23 Thread Peter Kriens via osgi-dev


Ok … on the top of my head …


public interface Bar {
void m1();
void m2();
}

@Component 
public class BarImpl implements Bar {
Deferred   delegate = new Deferred<>();

@Reference
void setExec( Executor e ) {
delegate.resolve( new BarImpl2(e) );
}


public void m1() {
delegate.getPromise().m1();
}   

public void m2() {
delegate.getPromise().m2();
}   
}

This works for you?

Kind regards,

Peter Kriens



> On 22 Jul 2018, at 22:51, David Leangen via osgi-dev  
> wrote:
> 
> 
> Hi Peter,
> 
> Thanks for the tip.
> 
> I’m not quite getting it. Would you be able to direct me to an example?
> 
> Thanks!
> =David
> 
> 
> 
>> On Jul 22, 2018, at 21:49, Peter Kriens  wrote:
>> 
>> In some cases (when the extra complexity was warranted) I let the component 
>> class act as a proxy to a delegate. I then get the delegate from a  Promise. 
>> So you just forward every method in your service interface to the delegate. 
>> There is a function in Eclipse that will create the delegation methods.
>> 
>> In general you want to afford this complexity and for example use a simple 
>> init() method that blocks until init is done. However, the delegate has some 
>> nice qualities if you switch more often than just at init.
>> 
>> Kind regards,
>> 
>>  Peter Kriens
>> 
>>> On 22 Jul 2018, at 10:35, David Leangen via osgi-dev 
>>>  wrote:
>>> 
>>> 
>>> Hi,
>>> 
>>> This may be more of a basic Java question, but I’ll ask it anyway because 
>>> it relates to “bouncing” and the handling of dynamic behavior.
>>> 
>>> In my @Activate method, I configure my component. Since the configuration 
>>> may be long-running (data is retrieved remotely), I use a Promise. But, the 
>>> component is available before it is actually “ready”. So far, this has not 
>>> been a problem.
>>> 
>>> It looks something like this:
>>> 
>>> @Reference private Store dataStore;
>>> 
>>> @Activate
>>> void activate() {
>>> configure(dataStore);
>>> }
>>> 
>>> void configure(Store withDataStore) {
>>> // Configuration is set up via a Promise, using a data store to retrieve 
>>> the data
>>> }
>>> 
>>> However, because there is some bouncing occurring, I think what is 
>>> happening is that configure() starts running in a different thread, but in 
>>> the meantime the reference to the dataStore is changed. The error log shows 
>>> that the data store is in an impossible state. After following a hunch, I 
>>> could confirm that the configureData process is running on a data store 
>>> service that was deactivated during bouncing.
>>> 
>>> What would be a good (and simple) strategy to handle this type of 
>>> long-running configuration, where the configuration is in a different 
>>> thread and depends on services that may come and go?
>>> 
>>> 
>>> Note: in the end, the component gets configured and the application runs, 
>>> but I would still like to be able to handle this situation properly.
>>> 
>>> 
>>> Thanks!
>>> =David
>>> 
>>> 
>>> ___
>>> OSGi Developer Mail List
>>> osgi-dev@mail.osgi.org
>>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>> 
> 
> ___
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev

___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev