Re: [osgi-dev] Dealing with bouncing

2018-08-26 Thread David Leangen via osgi-dev

Just to close this loop…

I just finished an iteration, following the advice presented in this thread. I 
think that I have been able to successfully deal with all my concurrency 
troubles.

Thanks for the tips!


Cheers,
=David



> On Jul 23, 2018, at 16:36, Tim Ward  wrote:
> 
> 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 
>>> mailto:osgi-dev@mail.osgi.org>> 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 
> mailto:osgi-dev@mail.osgi.org>> 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 

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

Re: [osgi-dev] Dealing with bouncing

2018-07-22 Thread David Leangen via osgi-dev

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

Re: [osgi-dev] Dealing with bouncing

2018-07-22 Thread Peter Kriens via osgi-dev
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-dev] Dealing with bouncing

2018-07-22 Thread David Leangen via osgi-dev

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