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

    Cancelling infinite loop in @Service bean

    piotrekde

      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
          welle

          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
            mp911de

            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

            1 of 1 people found this helpful
            • 3. Re: Cancelling infinite loop in @Service bean
              piotrekde

              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?)