Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-13542

Container does not enforce bean-managed concurrency for timeout methods

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Explained
    • Affects Version/s: 19.1.0.Final
    • Fix Version/s: None
    • Component/s: EJB
    • Labels:
      None
    • Steps to Reproduce:
      Hide

      Sample bean:

      import java.util.concurrent.locks.ReentrantLock;
      import javax.ejb.Asynchronous;
      import javax.ejb.ConcurrencyManagement;
      import javax.ejb.ConcurrencyManagementType;
      import javax.ejb.Schedule;
      import javax.ejb.Singleton;
      
      @Singleton
      @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
      public class MySingleton {
      
        private static final ReentrantLock locker = new ReentrantLock();
      
        @Schedule(persistent = false, second = "0/1", minute = "*", hour = "*")
        public void requestEntry() {
          long id = Thread.currentThread().getId();
          if (locker.tryLock()) {
            System.out.println("Please come in, " + id + "!");
            doSomething();
            locker.unlock();
          } else {
            System.err.println("Please wait outside, " + id + "!");
          }
        }
      
        private void doSomething() {
          int timeout = (int) (Math.random() * 8000 + 1000);
          try {
            Thread.sleep(timeout);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      
      }
      
      Show
      Sample bean: import java.util.concurrent.locks.ReentrantLock; import javax.ejb.Asynchronous; import javax.ejb.ConcurrencyManagement; import javax.ejb.ConcurrencyManagementType; import javax.ejb.Schedule; import javax.ejb.Singleton; @Singleton @ConcurrencyManagement(ConcurrencyManagementType.BEAN) public class MySingleton { private static final ReentrantLock locker = new ReentrantLock(); @Schedule(persistent = false , second = "0/1" , minute = "*" , hour = "*" ) public void requestEntry() { long id = Thread .currentThread().getId(); if (locker.tryLock()) { System .out.println( "Please come in, " + id + "!" ); doSomething(); locker.unlock(); } else { System .err.println( "Please wait outside, " + id + "!" ); } } private void doSomething() { int timeout = ( int ) ( Math .random() * 8000 + 1000); try { Thread .sleep(timeout); } catch (InterruptedException e) { e.printStackTrace(); } } }

      Description

      Bean-managed concurrency for @Singleton EJBs is not enforced for timeout methods annotated with @Schedule. When a timeout is fired while the previous one is still running, the timeout method is not called. Instead, WildFly logs a warning like the following:

      20:58:54,000 WARN  [org.jboss.as.ejb3.timer] (EJB default - 2) WFLYEJB0043: A previous execution of timer [id=aa716284-ef7b-4bb3-a356-a8ca187255c4 timedObjectId=myweb.myweb.MySingleton auto-timer?:true persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@303bd2d5 previousRun=Sun May 31 20:57:10 BRT 2020 initialExpiration=null intervalDuration(in milli sec)=0 nextExpiration=Sun May 31 20:58:54 BRT 2020 timerState=IN_TIMEOUT info=null] ScheduleExpression [second=0/1;minute=*;hour=*;dayOfMonth=*;month=*;dayOfWeek=*;year=*;timezoneID=null;start=null;end=null] is still in progress, skipping this overlapping scheduled execution at: Sun May 31 20:58:54 BRT 2020.
      

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  cfang Cheng Fang
                  Reporter:
                  fabiogsilva Fábio Silva
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  2 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: