Re: [osgi-dev] Life-cycle race condition

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

Hi Tim,

Thanks, and this is good advice. The example you give is when the thread is in 
the same component that is being deactivated. In this case, as you show, it is 
quite trivial to track the activation state of the component in order to shut 
down the thread.

In my case, the trouble I am having is that the long-running thread is in a 
component that is different from the component that is getting deactivated. For 
instance, building on your example:

@Component
public class MyClass {

   // Note that I am using a STATIC service
   @Reference private MyService myService;

   private final AtomicBoolean closed = new AtomicBoolean();

   @Activate
   void start() {
   new Thread(this::longStart).run()
   }


   @Deactivate
   void stop() {
   closed.set(true);
   }

   void longStart() {
   for(int i = 0; i < 100; i++) {

   // This only works if the service object is not stateful, otherwise 
we need
   // to do a check and throw away an intermediate invalidated result

   // Understood, but unfortunately the service object is stateful.

   // The problem is that the dependency can be deactivated at any 
time, and this
   // is happening before “closed" in this component get set to “true". 
I do not know how
   // to detect the deactivation of the dependency. I need to determine 
this pre-emptively,
   // not after-the-fact. Otherwise the result will be destructive.

   doSomethingWithMyService(myService);

   // Ideally I would like to do something like this:
   if (myServiceIsStillActive())
   doSomethingWithMyService(myService);
   }
   }
}

In the second example, there is a dynamic @Reference, so I see the point of 
using an AtomicReference. However, I am using a static @Reference, so I doubt 
that just putting in an AtomicReference will change the timing problem.

Any thoughts?



By the way, instead of using a “closed” variable, I am doing something like 
this:

@Activate
void activate()
{
executor = Executors.newSingleThreadExecutor();
}

void deactivate()
{
executor.shutdownNow();
}

Then I only need to test for Thread.interrupted(). I assume this has the same 
effect as having the check for “closed".

Cheers,
=David



> On Aug 1, 2018, at 16:59, Tim Ward  wrote:
> 
> Hi David,
> 
> In addition to interrupting the worker thread (which is a good idea). There 
> are a couple of useful things that you can do using the support from 
> java.util.concurrent. For example, setting a closed state:
> 
> 
> @Component
> public class MyClass {
> 
>private final AtomicBoolean closed = new AtomicBoolean();
> 
>@Activate
>void start() {
>new Thread(this::longStart).run()
>}
> 
> 
>@Deactivate
>void stop() {
>closed.set(true);
>}
> 
>void longStart() {
>for(int i = 0; i < 100; i++) {
>if(closed.get()) {
>break;
>}
>doSomething();
>}
>}
> }
> 
> Also if your references are dynamic then you should treat them carefully
> 
> @Component
> public class MyClass implements MySlowService {
> 
>private final AtomicReference myRef = new AtomicReference<>();
> 
>@Reference(policy=DYNAMIC)
>void setReference(MyService service) {
>myRef.set(service)
>}
> 
>void unsetReference(MyService service) {
>// Note that it is *not* safe to just do a set null, see Compendium 
> 112.5.12
>myRef.compareAndSet(service, null);
>}
> 
>public void longRunningTask() {
>for(int i = 0; i < 100; i++) {
>// This only works if the service object is not stateful, 
> otherwise we need
>// to do a check and throw away an intermediate invalidated result
> 
>MyService myService = myRef.get();
>doSomethingWithMyService(myService);
>}
>}
> }
> 
> I hope you find these helpful.
> 
> Tim
> 
>> On 1 Aug 2018, at 05:44, David Leangen via osgi-dev  
>> wrote:
>> 
>> 
>> Hi!
>> 
>> I am running into a situation where, what I think is happening is:
>> 
>> Component A gets instantiated
>> Component B
>> - references A
>> - gets satisfied once A is satisfied 
>> - kicks off a long-running process when one of its methods are called
>> - the long-running process is run in a different thread, with a Promise
>> Component A is no longer satisfied
>> But
>> - the long-running process is still running
>> - the long-running process now references an invalid Component A
>> - the long-running thread fails because of the invalid state of Component A
>> Component B is no longer satisfied
>> 
>> 
>> So, the long-running component messes things up, but its component has not 
>> yet shut down even though its process is still happily running in another 
>> thread.
>> 
>> I can think of two possible solutions, but not sure which is best and not 
>> sure how to implement:
>> 
>> 1) 

Re: [osgi-dev] Setting reference target in component

2018-08-01 Thread Alain Picard via osgi-dev
Thanks Tim. I had read that thread but didn't make the association. I think
my case falls between some of the described solutions and part of your
point in 2, a bit of redesign :)

Alain


On Tue, Jul 31, 2018 at 12:42 PM Tim Ward  wrote:

> This sounds like a variation on this question
>  asked a
> few weeks ago in the osgi-dev list.
>
> In summary, there are a couple of ways to achieve what you’re trying to
> do, and using configuration admin may or may not be the best approach given
> that you want to request an instance which you directly control the
> lifecycle of. Hopefully the thread will give you the answer that you’re
> looking for.
>
> Best Regards,
>
> Tim
>
> On 31 Jul 2018, at 13:24, Alain Picard via osgi-dev <
> osgi-dev@mail.osgi.org> wrote:
>
> I need to configure some Component to be session scoped. I have followed
> the article from Dirk at
> http://blog.vogella.com/2017/02/24/control-osgi-ds-component-instances-via-configuration-admin/
> which matches what I want.
>
> But in my case the Component that configures the service is also the has a
> reference to this service. I read a couple of SO about this (
> https://stackoverflow.com/questions/47393876/dynamically-setting-target-property-in-osgi-reference-annotatation
> and
> https://stackoverflow.com/questions/21166070/osgi-declarative-services-filter-references-at-runtime)
> but I'm struggling to figure out the best way to both specify a
> configuration as per the 1st article and then set the target in my
> component to the resulting instance (and/or getting a component
> configuration and set the target for my service).
>
> Thanks
> Alain
>
> ___
> 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] Life-cycle race condition

2018-08-01 Thread Tim Ward via osgi-dev
Hi David,

In addition to interrupting the worker thread (which is a good idea). There are 
a couple of useful things that you can do using the support from 
java.util.concurrent. For example, setting a closed state:


@Component
public class MyClass {

private final AtomicBoolean closed = new AtomicBoolean();

@Activate
void start() {
new Thread(this::longStart).run()
}


@Deactivate
void stop() {
closed.set(true);
}

void longStart() {
for(int i = 0; i < 100; i++) {
if(closed.get()) {
break;
}
doSomething();
}
}
}

Also if your references are dynamic then you should treat them carefully

@Component
public class MyClass implements MySlowService {

private final AtomicReference myRef = new AtomicReference<>();

@Reference(policy=DYNAMIC)
void setReference(MyService service) {
myRef.set(service)
}

void unsetReference(MyService service) {
// Note that it is *not* safe to just do a set null, see Compendium 
112.5.12
myRef.compareAndSet(service, null);
}

public void longRunningTask() {
for(int i = 0; i < 100; i++) {
// This only works if the service object is not stateful, otherwise 
we need
// to do a check and throw away an intermediate invalidated result

MyService myService = myRef.get();
doSomethingWithMyService(myService);
}
}
}

I hope you find these helpful.

Tim

> On 1 Aug 2018, at 05:44, David Leangen via osgi-dev  
> wrote:
> 
> 
> Hi!
> 
> I am running into a situation where, what I think is happening is:
> 
> Component A gets instantiated
> Component B
>  - references A
>  - gets satisfied once A is satisfied 
>  - kicks off a long-running process when one of its methods are called
>  - the long-running process is run in a different thread, with a Promise
> Component A is no longer satisfied
> But
>  - the long-running process is still running
>  - the long-running process now references an invalid Component A
>  - the long-running thread fails because of the invalid state of Component A
> Component B is no longer satisfied
> 
> 
> So, the long-running component messes things up, but its component has not 
> yet shut down even though its process is still happily running in another 
> thread.
> 
> I can think of two possible solutions, but not sure which is best and not 
> sure how to implement:
> 
> 1) Figure out a way to share an ExecutorService between “related” components 
> so that when one component 
>  shuts down it will signal to the other related components that their 
> threads are now interrupted
> 
> 2) In the long-running process, determine if the component that provides the 
> required service
>   is still active before continuing with the havoc-wreaking process
> 
> 
> Does this sound about right?
> 
> How would I actually accomplish either of these?
> 
> 
> 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