3 Replies Latest reply: May 26, 2011 10:09 AM by piotrekde RSS

Cancelling infinite loop in @Service bean

piotrekde Newbie

Hi,

 

My @Service bean has a method, which when invoked, runs forever (or up to the time when it will be cancelled). This method receives datagrams from socket (it's blocking operation), and forwards these datagrams into pooled beans which processes them. I'd like to have a possibility to cancel this loop, after invoking cancel() method. Here is simple code snippet:

 

 

@Service
MyServiceBean {

  @EJB
  DatagramsProcessor datagramsProcessor;

  private boolean isRunning; // shouldn't I use AtomicBoolean?

  void listen() {
    this.isRunning = true;
    while(isRunning) {
      Datagram d = socket.receive(); // blocking operation
      datagramsProcessor.process(d);      
    }
  }

  void cancel() {
    this.isRunning = false;
  }
}

 

It's very simple approach and it works as expected. However, when I try to shut down JBoss it stucks when trying to stop this service bean:

 

 

13:25:19,798 INFO  [EJBContainer] STOPPED EJB: eu.example.MyServiceBean ejbName: MyServiceBean

 

13:27:59,305 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.TransactionReaper_18] - TransactionReaper::check timeout for TX 7f000002:ac97:4dcfb2a7:210 in state  RUN

13:27:59,307 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_58] - Abort of action id 7f000002:ac97:4dcfb2a7:210 invoked while multiple threads active within it.

13:27:59,307 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.CheckedAction_2] - CheckedAction::check - atomic action 7f000002:ac97:4dcfb2a7:210 aborting with 1 threads active!

13:27:59,308 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.TransactionReaper_7] - TransactionReaper::doCancellations worker Thread[Thread-8,5,jboss] successfuly cancelled TX 7f000002:ac97:4dcfb2a7:210

 

 

As I expected, this approach is simple, but can result in transaction problems. If I change annotation from @Service to @Stateful and try to call cancel() method, exception related to concurrent access is thrown.

 

Is there any better way to cancel work running in while(true) loop? Or how can I improve this one, to be able to shut down JBoss.

I use EJB 3.0 with JBoss5.

 

Thanks in advance,

Piotr

  • 1. Cancelling infinite loop in @Service bean
    Anders Welen Apprentice

    What happens if you put a PreDestroy callback annotation on your cancel method?

     

    (I'm not sure it works though... probably not...)

  • 2. Cancelling infinite loop in @Service bean
    Mark Paluch Master

    Hi,

    how about creating a MBean, that launches and controls a Thread. In this Thread you can look up your EJB (not running in any Transaction-Timeouts). MBeans can be controlled via start/stop-Methods, so you'll get notified when JBoss stops and you stop your receive-Thread.

     

    An other way could be setting @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) at listen()-Method

     

    Best regards,

    Mark

  • 3. Re: Cancelling infinite loop in @Service bean
    piotrekde Newbie

    I' ve noticed, that if I change boolean -> AtomicBoolean and if loop is stopped before JBoss will receive shutdown signal, server stops in 99.% cases fine, without any error messages.

     

    Anyway, sometimes I have information about cancelled/timeouted transaction. In my opinion, setting @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) at listen() method may fix this issue, but I'am not sure, if with this annotation enabled, there is no possibility of race conditions (or some similar concurrent access related problems) when reading from socket. (On the other site, if it's @Service bean how such problems would be caused... is it possible at all?)