JLupin Next Server has mechanisms which enable the client to execute specific business services in certain thread pools. The following picture shows a functional diagram:

The execution of services in specific threads pools is for securing the separation of certain operations which may take a longer processing time from ones which have a short estimated processing time. Observe the following example.

We have 4 services A, B, C, D in our system.

Services: A, B call the "sampleSubsystem" subsystem in its source code. The operations executed by the subsystem have a long duration of time.

Services: C, D process quick mathematical operations in its source code and respond really quick.

Imagine a situation in which all services are running in a single thread pool and a large number of queries to A and B services are sent. A situation which then easily occurs is thread saturation and requests which were sent to C and D services are not processed. Clients of C and D services wait in pessimistic locking the same amount of time as clients of A and B services. With the separation of A, B, C and D services in separate pools of threads, thread pool saturation for A and B services do not affect the continuity of the processing of C and D services.

How is it handled by JLupin Next Server?

Regular expressions are the key to understanding the answer to this question. In simple words: before executing the service, the regular expression which is taken from the configuration is matched to a specific service name and if there is a match then the service is executed in any given thread pool. If the expression does not match, the service is executed in the default thread pool.

Observe the configuration example.

Spring's configuration file fragment:

    <bean id="sampleServiceI1" class="com.jlupin.sampleapp.common.service.SampleServiceImpl1">
    </bean>

    <bean id="firstSampleService" class="com.jlupin.sampleapp.service.FirstSampleService">
    </bean>

    <bean id="secondSampleService" class="com.jlupin.sampleapp.service.SecondSampleService">
    </bean>

    <bean id="thirdSampleService" class="com.jlupin.sampleapp.service.ThirdSampleService">
    </bean>

    <bean id="dateTimeService" class="com.jlupin.sampleapp.paramsfunction.service.impl.DateTimeServiceImpl">
    </bean>

    <bean id="sampleExceptionService_01" class="com.jlupin.sampleapp.service.SampleExceptionService_01">
    </bean>

    <bean id="sampleExceptionService_02" class="com.jlupin.sampleapp.service.SampleExceptionService_02">
    </bean>

    <bean id="sampleExceptionService_03" class="com.jlupin.sampleapp.service.SampleExceptionService_03">
    </bean>

    <bean id="sampleExceptionService_04" class="com.jlupin.sampleapp.service.SampleExceptionService_04">
    </bean>

    <bean id="sampleExceptionService_05" class="com.jlupin.sampleapp.service.SampleExceptionService_05">
    </bean>

    <bean id="sampleExceptionService_06" class="com.jlupin.sampleapp.service.SampleExceptionService_06">
    </bean>

    <bean id="sampleExceptionService_07" class="com.jlupin.sampleapp.service.SampleExceptionService_07">
    </bean>

Requirements for configuration

  • Services: firstSampleService, secondSampleService, thirdSampleService, dateTimeService should be executed in a single thread pool and other services in a separate thread pool.

Observe configurations - a full application file for firstSampleApplication - JLupinFirstSampleApplicationConfigurationImpl.java

public class JLupinFirstSampleApplicationConfigurationImpl implements JLupinLocalSingleProcessConfiguration{

    @Override
    public void before() {

    }

    @Override
    public void after() {

    }
    @Override
    public JLupinBaseServer getJLupinLocalBaseServer() {
        JLupinDefaultBaseServerImpl jLupinDefaultBaseServer = new JLupinDefaultBaseServerImpl("default");
        jLupinDefaultBaseServer.setThreadPoolSize(64);
        return jLupinDefaultBaseServer;
    }

    @Override
    public JLupinBaseServer getJLupinLocalCommandServer() {
        JLupinDefaultBaseServerImpl jLupinDefaultBaseServer = new JLupinDefaultBaseServerImpl("command");
        jLupinDefaultBaseServer.setThreadPoolSize(4);
        jLupinDefaultBaseServer.setWaitForFinishExecuteAllRequests(false);
        return jLupinDefaultBaseServer;
    }

    @Override
    public JLupinEntryPoint getJLupinLocalCommandEntryPoint() {
        return new JLupinLocalCommandEntryPointImpl();
    }

    @Override
    public JLupinEntryPoint getJLupinLocalEntryPoint() {

        JLupinDefaultEntryPointConfigurator jLupinDefaultEntryPointConfigurator =
                new JLupinDefaultEntryPointConfigurator();

        List sampleServiceNameRegExList = new ArrayList();
        sampleServiceNameRegExList.add("[Service][^Exception]");
        jLupinDefaultEntryPointConfigurator.addRegexServiceNameForThreadPoolSize(sampleServiceNameRegExList, 16);

        List sampleExceptionServiceNameRegExList = new ArrayList();
        sampleExceptionServiceNameRegExList.add("[sampleExceptionService{1}]_[d]");
        jLupinDefaultEntryPointConfigurator.addRegexServiceNameForThreadPoolSize(
                sampleExceptionServiceNameRegExList, 16);

        JLupinInvokeServiceStrategy jLupinInvokeServiceStrategy =
                new JLupinInvokeServiceStrategyInNewThreadFromPoolImpl(
                        jLupinDefaultEntryPointConfigurator,16);

        JLupinDefaultEntryPointImpl jLupinDefaultEntryPoint =
                new JLupinDefaultEntryPointImpl(jLupinInvokeServiceStrategy);

        return jLupinDefaultEntryPoint;
    }

    public  JLupinServiceProcessor getJLupinServiceProcessor() {
        JLupinServiceProcessor jLupinServiceProcessor = new JLupinDefaultServiceProcessorImpl();
        return jLupinServiceProcessor;
    }

    @Override
    public JLupinInnerServiceProcessor getJLupinInnerServiceProcessor() {
        return new JLupinDefaultInnerServiceProcessorImpl();
    }

    @Override
    public JLupinApplicationInvoker getJLupinApplicationInvoker() {

        JLupinClientSocketConfiguration clientSocketConfServer = new JLupinClientSocketConfiguration();
        clientSocketConfServer.setSocketAddressToConnectServer(new InetSocketAddress("localhost", 9090));
        clientSocketConfServer.setSoTimeout(30000);

        JLupinBalancer jLupinBalancer = new JLupinOutputParameterAnalyzerAlgSocketBalancerImpl(
                4, getJLupinLogger(), getJLupinSerializer(),clientSocketConfServer);

        JLupinDelegator jLupinBalanceDelegator = new JLupinDefaultBalanceProxyDelegatorImpl(jLupinBalancer);

        return new JLupinDefaultApplicationInvokerImpl(new JLupinDelegator[] {jLupinBalanceDelegator});
    }

    @Override
    public JLupinApplicationContainer getJLupinApplicationContainer() {
        JLupinSingleApplicationContainerForLocalProcessImpl jLupinSingleApplicationContainerForLocalProcess =
                new JLupinSingleApplicationContainerForLocalProcessImpl(
                        new String[] {"classpath:spring-services.xml",
                                "classpath:spring-health-checking-services.xml"});
        return jLupinSingleApplicationContainerForLocalProcess;
    }

    @Override
    public JLupinLogger getJLupinLogger() {
        return JLupinLoggerOverLog4jImpl.getInstance();
    }

    @Override
    public JLupinSerializer getJLupinSerializer() {
        return JLupinDefaultSerializerImpl.getInstance();
    }
}

Please take a closer look at the getJLupinLocalEntryPoint method:

@Override
    public JLupinEntryPoint getJLupinLocalEntryPoint() {

        JLupinDefaultEntryPointConfigurator jLupinDefaultEntryPointConfigurator =
                new JLupinDefaultEntryPointConfigurator();

        List sampleServiceNameRegExList = new ArrayList();
        sampleServiceNameRegExList.add("[Service][^Exception]");
        jLupinDefaultEntryPointConfigurator.addRegexServiceNameForThreadPoolSize(sampleServiceNameRegExList, 16);

        List sampleExceptionServiceNameRegExList = new ArrayList();
        sampleExceptionServiceNameRegExList.add("[sampleExceptionService{1}]_[d]");
        jLupinDefaultEntryPointConfigurator.addRegexServiceNameForThreadPoolSize(
                sampleExceptionServiceNameRegExList, 16);

        JLupinInvokeServiceStrategy jLupinInvokeServiceStrategy =
                new JLupinInvokeServiceStrategyInNewThreadFromPoolImpl(
                        jLupinDefaultEntryPointConfigurator,16);

        JLupinDefaultEntryPointImpl jLupinDefaultEntryPoint =
                new JLupinDefaultEntryPointImpl(jLupinInvokeServiceStrategy);

        return jLupinDefaultEntryPoint;
    }

The first step is to create the JLupinDefaultEntryPointConfigurator configuration object. It takes in the addRegexServiceNameForThreadPoolSize method a list of regular expressions that will be searched upon receiving the service name. If an expression is matched, a specific thread pool will be taken (the size of which is defined in the second parameter - in this example, 16). As it is shown in the foregoing example, one pool of threads will handle all services which have the 'Service' string in their name however, there is no 'Exception' string in their name. The second thread pool will handle all services with the $sampleExceptionService_ number string in their name.

In the next steps we create an instances of JLupinInvokeServiceStrategy interface - JlupinInvokeServiceStrategyInNewThreadFromPoolImpl.The newly created jLupinDefaultEntryPointConfigurator configuration is given in the constructor parameter. The second parameter is the size of the default pool, which is used in a situation when the expression does not match the name of the service.

As a result of the "firstSampleService" service's execution, we should observe the following entry in the application's side log file (refer to the "Logging" chapter) (in order to observe the entry the DEBUG logging level should be configured).

2015-03-09 10:29:43,202 DEBUG [com.jlupin.impl.entrypoint.defaults.strategy.invoke.impl.JLupinInvokeServiceStrategyInNewThreadFromPoolImpl] (pool-7-thread-2)  MESSAGE ID:23 LINE:91 LOG:try match pattern:[Service][^Exception] to execute service:firstSampleService in dedicated thread pool
2015-03-09 10:29:43,202 DEBUG [com.jlupin.impl.entrypoint.defaults.strategy.invoke.impl.JLupinInvokeServiceStrategyInNewThreadFromPoolImpl] (pool-7-thread-2)  MESSAGE ID:24 LINE:94 LOG:pattern:[Service][^Exception] matched to execute service name:firstSampleService
2015-03-09 10:29:43,202 DEBUG [com.jlupin.impl.entrypoint.defaults.strategy.invoke.impl.JLupinInvokeServiceStrategyInNewThreadFromPoolImpl] (pool-7-thread-2)  MESSAGE ID:25 LINE:111 LOG:pattern to execute service name:firstSampleService found, service:firstSampleService will be executed in dedicated thread pool