Re: [osgi-dev] Felix resolver takes forever to resolve dependencies

2018-08-02 Thread Peter Kriens via osgi-dev
This is a Felix issue :-( 

* Did you find the -runbundles with the Bndtools resolver? How long did that 
take?
* Did you upgrade to the latest Felix?
* Did you try an older version?
* Did you try Equinox?

You might want to post it on the Apache Felix list. They probably have some 
secret system properties you can set to get more diagnostic info.

Sorry I can't help you more … 

Kind regards,

Peter Kriens




> On 2 Aug 2018, at 16:41, Nhut Thai Le via osgi-dev  
> wrote:
> 
> Hello,
> 
> We are trying to integrate Keycloak admin-client and zk into our web app 
> running on felix using bndtool.
> 
> If we use our web app with Keycloak admin-client alone, it's fine.
> 
> If we use our web app with zk alone, it's also fine.
> 
> When adding both Keycloak admin-client and zk, we are not able to start the 
> container from bndrun. Looks like the framework resolver get stuck in 
> resolving dependencies. Here is the stack of the main thread:
> Thread [main] (Suspended) 
>   waiting for: AtomicInteger  (id=29) 
>   Object.wait(long) line: not available [native method]   
>   AtomicInteger(Object).wait() line: 502  
>   ResolverImpl$EnhancedExecutor.await() line: 2523
>   ResolverImpl.calculatePackageSpaces(ResolveSession, Candidates, 
> Collection) line: 1217
>   ResolverImpl.checkConsistency(ResolveSession, Candidates, 
> Map) line: 572  
>   ResolverImpl.findValidCandidates(ResolveSession, 
> Map) line: 532   
>   ResolverImpl.doResolve(ResolveSession) line: 395
>   ResolverImpl.resolve(ResolveContext, Executor) line: 377
>   ResolverImpl.resolve(ResolveContext) line: 331  
>   StatefulResolver.resolve(Set, Set) 
> line: 478
>   Felix.resolveBundles(Collection) line: 4108 
>   FrameworkWiringImpl.resolveBundles(Collection) line: 133
>   PackageAdminImpl.resolveBundles(Bundle[]) line: 267 
>   Launcher.startBundles(List) line: 489   
>   Launcher.activate() line: 423   
>   Launcher.run(String[]) line: 301
>   Launcher.main(String[]) line: 147   
> 
> A small note here is that Keycloak admin-client uses resteasy which is not an 
> osgi bundle so I wrap both admin-client, resteasy and its dependencies in an 
> osgi bundle and enabling service loader mediator header so that the service 
> files provided in the resteasy dependencies can be loaded.
> 
> For debugging I downloaded the source of org.apache.felix.framework but it 
> has no resolver/RersolverImpl class
> 
> I'm not sure what to do to debug this.
> 
> Thai
> 
> 
> ___
> 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] Felix resolver takes forever to resolve dependencies

2018-08-02 Thread Nhut Thai Le via osgi-dev
 Hello,

We are trying to integrate Keycloak admin-client and zk into our web app
running on felix using bndtool.

If we use our web app with Keycloak admin-client alone, it's fine.

If we use our web app with zk alone, it's also fine.

When adding both Keycloak admin-client and zk, we are not able to start the
container from bndrun. Looks like the framework resolver get stuck in
resolving dependencies. Here is the stack of the main thread:
Thread [main] (Suspended)
waiting for: AtomicInteger  (id=29)
Object.wait(long) line: not available [native method]
AtomicInteger(Object).wait() line: 502
ResolverImpl$EnhancedExecutor.await() line: 2523
ResolverImpl.calculatePackageSpaces(ResolveSession, Candidates,
Collection) line: 1217
ResolverImpl.checkConsistency(ResolveSession, Candidates,
Map) line: 572
ResolverImpl.findValidCandidates(ResolveSession,
Map) line: 532
ResolverImpl.doResolve(ResolveSession) line: 395
ResolverImpl.resolve(ResolveContext, Executor) line: 377
ResolverImpl.resolve(ResolveContext) line: 331
StatefulResolver.resolve(Set, Set) line: 478
Felix.resolveBundles(Collection) line: 4108
FrameworkWiringImpl.resolveBundles(Collection) line: 133
PackageAdminImpl.resolveBundles(Bundle[]) line: 267
Launcher.startBundles(List) line: 489
Launcher.activate() line: 423
Launcher.run(String[]) line: 301
Launcher.main(String[]) line: 147

A small note here is that Keycloak admin-client uses resteasy which is not
an osgi bundle so I wrap both admin-client, resteasy and its dependencies
in an osgi bundle and enabling service loader mediator header so that the
service files provided in the resteasy dependencies can be loaded.

For debugging I downloaded the source of org.apache.felix.framework but it
has no resolver/RersolverImpl class

I'm not sure what to do to debug this.

Thai
___
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-02 Thread Peter Kriens via osgi-dev
Yup, it got a bit windy ;-) I put it on my website as a blog since I've no good 
other place at the moment.

http://aqute.biz/2018/08/02/the-service-window.html 


Let me know if things are unclear. Kind regards,

Peter Kriens


> On 2 Aug 2018, at 11:58, David Leangen via osgi-dev  
> wrote:
> 
> 
> Wow! That is a lot to digest.
> 
> I’ll need to get back to you in a few days/weeks/months/years. :-D
> 
> Thanks so much!!
> 
> 
> Cheers,
> =David
> 
> 
> 
> 
>> On Aug 2, 2018, at 18:38, Peter Kriens > > wrote:
>> 
>> 
>> ## Keep Passing the Open Windows
>> 
>> You did read the classic [v2Archive OSGi enRoute App note][5] about this 
>> topic? It has been archived by the OSGi to [v2Archive OSGi enRoute web 
>> site][3]. It handles a lot of similar cases. There is an accompanying 
>> workspace [v2Archive OSGi enRoute osgi.enroute.examples.concurrency 
>> ][7]
>> 
>> Anyway, I am not sure if you want to solve this pragmatic or pure?
>> 
>> ## Pragmatic 
>> 
>> Pragmatic means there is a tiny chance you hit the window where you check if 
>> the MyService is unregistered and then use it. If you're really unlucky you 
>> just hit the unregistration after you checked it but before you can use it. 
>> It works when the unregistration of MyService is rare and the work is long. 
>> Yes, it can fail but so can anything so you should be prepared for it. 
>> 
>> Pragmatic works best as follows:
>> 
>>@Component
>>public class MyClass extends Thread {   
>>   @Reference MyService myService;
>>
>>   @Activate void activate()  { start(); }
>>   @Deactivate void deactivate()  { interrupt(); }
>>
>>   public void run() {
>>  while (!isInterrupted()) {
>> try {
>> MyResult result = doHardWork();
>> if (!isInterrupted())
>> myService.setResult(result);
>> } catch (Exception e) { /* TODO */ }
>>  }
>>   }
>>}
>> 
>> Clearly there is a race condition. 
>> 
>> 
>> 
>> 
>> ## Pure 
>> 
>> I once had a use case where we had whiteboard listeners that received 
>> events. The frequency and some not so good event listeners that took too 
>> much time in their callback. This created a quite long window where it could 
>> fail so it often did. For that use case I created a special highly optimized 
>> class that could delay the removal of the listener while it was being 
>> dispatched. To make it have absolutely minimal overhead was tricky, I even 
>> made an Alloy model of it that found some design errors. Anyway, sometimes 
>> you have pick one of the bad sides, this was one where delaying the 
>> deactivate was worth it.
>> 
>> So how would you make this 'purer' by delaying the deactivation until you 
>> stopped using it? Since the service is still supposed to be valid during 
>> deactivate we could make the setResult() and the deactivate() methods 
>> exclude each other. That is, we need to make sure that no interrupt can 
>> happen when we check for the isInterrupted() and call myService.setResult(). 
>> We could use heavy locks but synchronized works fine for me when you realize 
>> some of its caveats:
>> 
>> * Short blocks
>> * Ensure you cannot create deadlocks
>> 
>> So there must be an explicit contract that the MyService is not going to 
>> stay away for a long time nor call lots of other unknown code that could 
>> cause deadlocks. After all, we're blocking the deactivate() method which is 
>> very bad practice in general. So you will trade off one purity for another.
>> 
>>@Component
>>public class MyClass extends Thread {   
>>   @Reference MyService myService;
>>
>>   @Activate void activate()  { start(); }
>>   @Deactivate synchronized void deactivate() { interrupt(); }
>>
>>   public void run() {
>>  while (!isInterrupted()) {
>> try {
>> MyResult result = doHardWork();
>>  synchronized(this) {
>> if (!isInterrupted()) {
>> myService.setResult(result);
>>  }
>>  }
>> } catch (Exception e) { /* TODO */ }
>>  }
>>   }
>>}
>> 
>> This guarantees what you want … However (you knew this was coming!) there is 
>> a reason the service gets deactivated. Even though the _service_ is still 
>> valid at that point, there is a reason the _service object_ indicated its 
>> unwillingness to play. For example, if MyService was remoted then the 
>> connection might have been lost. In general, when you call a service you 
>> should be prepared that it fails. (That is why you should always take 
>> exceptions into account even if they're not checked.)
>> 
>> ## Better API
>> 
>> The best solution is usually to turn the problem around. This 

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

2018-08-02 Thread Tim Ward via osgi-dev
As Peter has said, once you go asynchronous and/or long running the possibility 
that things can go wrong increases rapidly. That isn’t to say that your 
solution will need to be as involved as some of the ones that Peter is 
suggesting. It honestly sounds as though you could avoid this problem through 
the use of a couple of “closed” checks in the relevant components, but again it 
would be easier to tell for certain if you could share the code.

Best Regards,

Tim 

> On 2 Aug 2018, at 10:58, David Leangen via osgi-dev  
> wrote:
> 
> 
> Wow! That is a lot to digest.
> 
> I’ll need to get back to you in a few days/weeks/months/years. :-D
> 
> Thanks so much!!
> 
> 
> Cheers,
> =David
> 
> 
> 
> 
>> On Aug 2, 2018, at 18:38, Peter Kriens > > wrote:
>> 
>> 
>> ## Keep Passing the Open Windows
>> 
>> You did read the classic [v2Archive OSGi enRoute App note][5] about this 
>> topic? It has been archived by the OSGi to [v2Archive OSGi enRoute web 
>> site][3]. It handles a lot of similar cases. There is an accompanying 
>> workspace [v2Archive OSGi enRoute osgi.enroute.examples.concurrency 
>> ][7]
>> 
>> Anyway, I am not sure if you want to solve this pragmatic or pure?
>> 
>> ## Pragmatic 
>> 
>> Pragmatic means there is a tiny chance you hit the window where you check if 
>> the MyService is unregistered and then use it. If you're really unlucky you 
>> just hit the unregistration after you checked it but before you can use it. 
>> It works when the unregistration of MyService is rare and the work is long. 
>> Yes, it can fail but so can anything so you should be prepared for it. 
>> 
>> Pragmatic works best as follows:
>> 
>>@Component
>>public class MyClass extends Thread {   
>>   @Reference MyService myService;
>>
>>   @Activate void activate()  { start(); }
>>   @Deactivate void deactivate()  { interrupt(); }
>>
>>   public void run() {
>>  while (!isInterrupted()) {
>> try {
>> MyResult result = doHardWork();
>> if (!isInterrupted())
>> myService.setResult(result);
>> } catch (Exception e) { /* TODO */ }
>>  }
>>   }
>>}
>> 
>> Clearly there is a race condition. 
>> 
>> 
>> 
>> 
>> ## Pure 
>> 
>> I once had a use case where we had whiteboard listeners that received 
>> events. The frequency and some not so good event listeners that took too 
>> much time in their callback. This created a quite long window where it could 
>> fail so it often did. For that use case I created a special highly optimized 
>> class that could delay the removal of the listener while it was being 
>> dispatched. To make it have absolutely minimal overhead was tricky, I even 
>> made an Alloy model of it that found some design errors. Anyway, sometimes 
>> you have pick one of the bad sides, this was one where delaying the 
>> deactivate was worth it.
>> 
>> So how would you make this 'purer' by delaying the deactivation until you 
>> stopped using it? Since the service is still supposed to be valid during 
>> deactivate we could make the setResult() and the deactivate() methods 
>> exclude each other. That is, we need to make sure that no interrupt can 
>> happen when we check for the isInterrupted() and call myService.setResult(). 
>> We could use heavy locks but synchronized works fine for me when you realize 
>> some of its caveats:
>> 
>> * Short blocks
>> * Ensure you cannot create deadlocks
>> 
>> So there must be an explicit contract that the MyService is not going to 
>> stay away for a long time nor call lots of other unknown code that could 
>> cause deadlocks. After all, we're blocking the deactivate() method which is 
>> very bad practice in general. So you will trade off one purity for another.
>> 
>>@Component
>>public class MyClass extends Thread {   
>>   @Reference MyService myService;
>>
>>   @Activate void activate()  { start(); }
>>   @Deactivate synchronized void deactivate() { interrupt(); }
>>
>>   public void run() {
>>  while (!isInterrupted()) {
>> try {
>> MyResult result = doHardWork();
>>  synchronized(this) {
>> if (!isInterrupted()) {
>> myService.setResult(result);
>>  }
>>  }
>> } catch (Exception e) { /* TODO */ }
>>  }
>>   }
>>}
>> 
>> This guarantees what you want … However (you knew this was coming!) there is 
>> a reason the service gets deactivated. Even though the _service_ is still 
>> valid at that point, there is a reason the _service object_ indicated its 
>> unwillingness to play. For example, if MyService was remoted then the 
>> connection might have been lost. In general, when you call a service you 
>> should be prepared that it fails. (That is why 

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

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

Wow! That is a lot to digest.

I’ll need to get back to you in a few days/weeks/months/years. :-D

Thanks so much!!


Cheers,
=David




> On Aug 2, 2018, at 18:38, Peter Kriens  wrote:
> 
> 
> ## Keep Passing the Open Windows
> 
> You did read the classic [v2Archive OSGi enRoute App note][5] about this 
> topic? It has been archived by the OSGi to [v2Archive OSGi enRoute web 
> site][3]. It handles a lot of similar cases. There is an accompanying 
> workspace [v2Archive OSGi enRoute osgi.enroute.examples.concurrency 
> ][7]
> 
> Anyway, I am not sure if you want to solve this pragmatic or pure?
> 
> ## Pragmatic 
> 
> Pragmatic means there is a tiny chance you hit the window where you check if 
> the MyService is unregistered and then use it. If you're really unlucky you 
> just hit the unregistration after you checked it but before you can use it. 
> It works when the unregistration of MyService is rare and the work is long. 
> Yes, it can fail but so can anything so you should be prepared for it. 
> 
> Pragmatic works best as follows:
> 
>@Component
>public class MyClass extends Thread {   
>   @Reference MyService myService;
>
>   @Activate void activate()   { start(); }
>   @Deactivate void deactivate()   { interrupt(); }
>
>   public void run() {
>  while (!isInterrupted()) {
> try {
> MyResult result = doHardWork();
> if (!isInterrupted())
> myService.setResult(result);
> } catch (Exception e) { /* TODO */ }
>  }
>   }
>}
> 
> Clearly there is a race condition. 
> 
> 
> 
> 
> ## Pure 
> 
> I once had a use case where we had whiteboard listeners that received events. 
> The frequency and some not so good event listeners that took too much time in 
> their callback. This created a quite long window where it could fail so it 
> often did. For that use case I created a special highly optimized class that 
> could delay the removal of the listener while it was being dispatched. To 
> make it have absolutely minimal overhead was tricky, I even made an Alloy 
> model of it that found some design errors. Anyway, sometimes you have pick 
> one of the bad sides, this was one where delaying the deactivate was worth it.
> 
> So how would you make this 'purer' by delaying the deactivation until you 
> stopped using it? Since the service is still supposed to be valid during 
> deactivate we could make the setResult() and the deactivate() methods exclude 
> each other. That is, we need to make sure that no interrupt can happen when 
> we check for the isInterrupted() and call myService.setResult(). We could use 
> heavy locks but synchronized works fine for me when you realize some of its 
> caveats:
> 
> * Short blocks
> * Ensure you cannot create deadlocks
> 
> So there must be an explicit contract that the MyService is not going to stay 
> away for a long time nor call lots of other unknown code that could cause 
> deadlocks. After all, we're blocking the deactivate() method which is very 
> bad practice in general. So you will trade off one purity for another.
> 
>@Component
>public class MyClass extends Thread {   
>   @Reference MyService myService;
>
>   @Activate void activate()   { start(); }
>   @Deactivate synchronized void deactivate()  { interrupt(); }
>
>   public void run() {
>  while (!isInterrupted()) {
> try {
> MyResult result = doHardWork();
>   synchronized(this) {
> if (!isInterrupted()) {
> myService.setResult(result);
>   }
>   }
> } catch (Exception e) { /* TODO */ }
>  }
>   }
>}
> 
> This guarantees what you want … However (you knew this was coming!) there is 
> a reason the service gets deactivated. Even though the _service_ is still 
> valid at that point, there is a reason the _service object_ indicated its 
> unwillingness to play. For example, if MyService was remoted then the 
> connection might have been lost. In general, when you call a service you 
> should be prepared that it fails. (That is why you should always take 
> exceptions into account even if they're not checked.)
> 
> ## Better API
> 
> The best solution is usually to turn the problem around. This clearly can 
> only happen when you can influence the API so that is often not a choice. If 
> you can, you can pass a Promise to the myService and calculate in the 
> background. Clearly that means you keep churning doing the hard work. Unless 
> the calculation is very expensive and the unregistration happens often, doing 
> the calculation unnecessary should normally have no practical concerns. If it 
> is, you might want to consider CompletableFuture instead of Promise since it 
> has a cancel() method. (We rejected a cancel 

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

2018-08-02 Thread Peter Kriens via osgi-dev

## Keep Passing the Open Windows

You did read the classic [v2Archive OSGi enRoute App note][5] about this topic? 
It has been archived by the OSGi to [v2Archive OSGi enRoute web site][3]. It 
handles a lot of similar cases. There is an accompanying workspace [v2Archive 
OSGi enRoute osgi.enroute.examples.concurrency 
][7]

Anyway, I am not sure if you want to solve this pragmatic or pure?

## Pragmatic 

Pragmatic means there is a tiny chance you hit the window where you check if 
the MyService is unregistered and then use it. If you're really unlucky you 
just hit the unregistration after you checked it but before you can use it. It 
works when the unregistration of MyService is rare and the work is long. Yes, 
it can fail but so can anything so you should be prepared for it. 

Pragmatic works best as follows:

   @Component
   public class MyClass extends Thread {   
  @Reference MyService myService;
   
  @Activate void activate() { start(); }
  @Deactivate void deactivate() { interrupt(); }
   
  public void run() {
 while (!isInterrupted()) {
try {
MyResult result = doHardWork();
if (!isInterrupted())
myService.setResult(result);
} catch (Exception e) { /* TODO */ }
 }
  }
   }

Clearly there is a race condition. 




## Pure 

I once had a use case where we had whiteboard listeners that received events. 
The frequency and some not so good event listeners that took too much time in 
their callback. This created a quite long window where it could fail so it 
often did. For that use case I created a special highly optimized class that 
could delay the removal of the listener while it was being dispatched. To make 
it have absolutely minimal overhead was tricky, I even made an Alloy model of 
it that found some design errors. Anyway, sometimes you have pick one of the 
bad sides, this was one where delaying the deactivate was worth it.

So how would you make this 'purer' by delaying the deactivation until you 
stopped using it? Since the service is still supposed to be valid during 
deactivate we could make the setResult() and the deactivate() methods exclude 
each other. That is, we need to make sure that no interrupt can happen when we 
check for the isInterrupted() and call myService.setResult(). We could use 
heavy locks but synchronized works fine for me when you realize some of its 
caveats:

* Short blocks
* Ensure you cannot create deadlocks

So there must be an explicit contract that the MyService is not going to stay 
away for a long time nor call lots of other unknown code that could cause 
deadlocks. After all, we're blocking the deactivate() method which is very bad 
practice in general. So you will trade off one purity for another.

   @Component
   public class MyClass extends Thread {   
  @Reference MyService myService;
   
  @Activate void activate() { start(); }
  @Deactivate synchronized void deactivate(){ interrupt(); }
   
  public void run() {
 while (!isInterrupted()) {
try {
MyResult result = doHardWork();
synchronized(this) {
if (!isInterrupted()) {
myService.setResult(result);
}
}
} catch (Exception e) { /* TODO */ }
 }
  }
   }

This guarantees what you want … However (you knew this was coming!) there is a 
reason the service gets deactivated. Even though the _service_ is still valid 
at that point, there is a reason the _service object_ indicated its 
unwillingness to play. For example, if MyService was remoted then the 
connection might have been lost. In general, when you call a service you should 
be prepared that it fails. (That is why you should always take exceptions into 
account even if they're not checked.)

## Better API

The best solution is usually to turn the problem around. This clearly can only 
happen when you can influence the API so that is often not a choice. If you 
can, you can pass a Promise to the myService and calculate in the background. 
Clearly that means you keep churning doing the hard work. Unless the 
calculation is very expensive and the unregistration happens often, doing the 
calculation unnecessary should normally have no practical concerns. If it is, 
you might want to consider CompletableFuture instead of Promise since it has a 
cancel() method. (We rejected a cancel since it makes the Promise mutable, but 
admittedly it is useful. However, it has the same race issues as we discuss 
here.)

   @Component
   public class MyClass {
   
  @Reference MyService myService;
  @Reference PromiseFactory promiseFactory;

  @Activate void activate() { 
Promise result = promiseFactory.submit( this::doHardWork );

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

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

Are you able to share this code, because it sounds as though the thread 
signalling model you’re using is wrong? 

From what you’re saying it sounds like the problem is in this other component. 
Specifically, that it is performing long running work that isn’t paying 
attention to its own deactivation state. Equally, there’s no need for a 
"myServiceIsStillActive()” check because you should only ever care about 
whether your own component is active. If a service dependency is deactivated 
then it will be unregistered *first* so that the dependent component gets 
deactivated first. This stops you from having to care about anyone’s lifecycle 
but your own.

As for using shutdownNow(). This is *encouraged* to interrupt the threads, but 
not guaranteed. You also need to make sure to actually check the interrupt 
status. As it sounds like your component gives up control of the thread into 
another component which has the problem then this may require more extensive 
changes. I would need to see code to be sure.

Best Regards,

Tim

> On 2 Aug 2018, at 01:01, David Leangen via osgi-dev  
> wrote:
> 
> 
> 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