Announcement Announcement Module
Collapse
No announcement yet.
Failed to acquire the pool semaphore in empty pool Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Failed to acquire the pool semaphore in empty pool

    Hello... i'm facing a problem when looking up my bean in test phase.
    To stress this bean, I'm using a JMeter test case with 100 simultaneously threads. Each thread perform an EJB lookUp for myWorkerBean defined in my applicationContext.xml as follows

    HTML Code:
    <jee:local-slsb lookup-home-on-startup="false" id="myWorkerBean" business-interface="MyWorkerInterface"
            jndi-name="MyWorkerBean/local" />
    Each looked up instance performs a call to MyWorkerInterface.execute(WorkRequest) method that slleps around 60.000 mills. But only first 30 lookups will perform succesfully and the remaining 70 will fail with "Fail to aquire pool semaphore, strictTimeout=-1" error because my bean class is annotated with strict max pool size = 30 and will be discarded.
    At this moment, I have 30 bean instances filling the pool during 60 seconds and if I check the MBean for MyWorkerBean in jmx-console shows AvailableCount attribute equals 30.

    After 60 seconds all 30 instances perform succesfully. Then, I run 100 more jmeter threads again, but this time all lookups blows with "Fail to aquire pool semaphore, strictTimeout=-1" and the MBean for MyWorkerBean in jmx-console shows AvailableCount equals 0 (but it should mark 30 again). What it means: for some reason that first 30 bean instances were not released.

    See the code:

    Code:
    public interface MyWorkerInterface
    {
        public WorkResponse execute(WorkRequest request);
    }
    Code:
    @javax.jws.WebService(portName = "MyWorkerWSPort", name = "MyWorker", serviceName = "MyWorker")
    public class MyWorkerWS extends SpringSupport implements MyWorkerInterface {
     
        @javax.jws.WebMethod(operationName = "execute")
        @javax.jws.soap.SOAPBinding(parameterStyle = ParameterStyle.BARE)
        @javax.jws.WebResult(name = "workResponse", partName = "workResponse", targetNamespace = "http://ws.working.my.com/")
        public WorkResponse execute(
            @javax.jws.WebParam(mode = Mode.IN, name = "work", partName = "work") 
            WorkRequest request) 
        {
     
            final int startingDepth = NDC.getDepth();
            WorkResponse response = null;
            try {
                //Here I'm looking up my bean via Spring
                MyWorkerInterface worker = (MyWorkerInterface) super.getBeanFactory().getBean("myWorkerBean");
     
                //Performs around 60.000ms
                response = worker.execute(request);            
            } catch (org.springframework.beans.BeansException beansException) {
                LoggerHelper.error("Application error", beansException);
            } catch (EJBException ejbException) {
     
                final String errorMessage = 
                    org.apache.commons.lang.StringUtils.defaultString(ejbException.getMessage());
     
                if (errorMessage.startsWith("Failed to acquire the pool semaphore")) {
                    // MyWorkerInterface.execute(WorkRequest) method is delayed for more than 20000ms.
                    // When the execute method backs to its normal execution time this EJBException is still happening
                    // but the pool seems to be empty
                    LoggerHelper.error("Pool is full because MyWorkerInterface.execute(WorkRequest) is" +
                            "taking more time than normal to perform.", ejbException);
                } 
                else {
                    LoggerHelper.error("ejb error", ejbException);
                }
            }
            return response;
        }
    }
    Code:
    @Clustered
    @Local(MyWorkerInterface.class)
    @Stateless(name = "MyWorkerBean")
    @Interceptors(value = { SpringBeanAutowiringInterceptor.class, LoggingInterceptor.class })
    @RolesAllowed(value = "client")
    @Pool(value = PoolDefaults.POOL_IMPLEMENTATION_STRICTMAX, maxSize = 30)
    public class MyWorkerBean implements MyWorkerInterface {
     
        @RolesAllowed("client")
        @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
        public WorkResponse execute(final WorkRequest workRequest) {
     
            long start = System.currentTimeMillis();
     
            WorkExchange exchange = new WorkExchange();
            exchange.setWorkRequest(workRequest);
     
             //Please ignore try/catch
            Thread.sleep(60000);
     
            LoggerUtil.info("Operation time: " + (System.currentTimeMillis() - start));
     
            // WorkExchange.workResponse have been set by MDB
            WorkResponse response = exhange.getWorkResponse();
     
            return response;
        }
    }
    Code:
    public class SpringSupport {
     
        protected final org.apache.log4j.Logger logger = 
            org.apache.log4j.Logger.getLogger(this.getClass());
     
        @javax.annotation.Resource
        private javax.xml.ws.WebServiceContext webServiceContext;
     
        private org.springframework.context.ApplicationContext cachedApplicationContext;
     
        protected org.springframework.beans.factory.BeanFactory getBeanFactory() {
            if (cachedApplicationContext != null) {
                return cachedApplicationContext;
            }
            if (webServiceContext == null) {
                return null;
            }
            javax.xml.ws.handler.MessageContext messageContext = webServiceContext.getMessageContext();
            if (messageContext == null) {
                return null;
            }
            javax.servlet.ServletContext servletContext = 
                (javax.servlet.ServletContext) messageContext.get(
                        javax.xml.ws.handler.MessageContext.SERVLET_CONTEXT);
     
            if (servletContext == null) {
                return null;
            }
            this.cachedApplicationContext = 
                (org.springframework.context.ApplicationContext) servletContext
                .getAttribute(
                        org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
            return cachedApplicationContext;
        }
    }
    I appreciate any help

    thanks
    Last edited by garrydias; Sep 13th, 2011, 02:57 PM.

  • #2
    Failed to acquire the pool semaphore in empty pool

    I made a mistake.

    The error "Failed to acquire pool semaphore" occurs at method invocation. The lookup occurs normally. The exception is thrown in this line

    response = worker.execute(request);

    (still searching a solution...)

    Comment


    • #3
      You create a proxy which implements MaterialDaoLocal (well the lookup does that) and you expect to convert it to a concrete implementation (MaterialDaoBean) because it is a dynamic proxy that isn't obviously isn't going to work. You should program to the interface (MaterialDaoLocal)...

      Comment

      Working...
      X