Announcement Announcement Module
Collapse
No announcement yet.
Multithreading on serviceActivator Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Multithreading on serviceActivator

    Hi All,

    This is my first post on the forum & urgently require some experts help.
    Here is the sample piece of code

    Code in configuration file

    <si:channel id="routerOtherProf">
    <si:dispatcher load-balancer="round-robin" failover="true"
    task-executor="taskPoolExecutor" />
    </si:channel>

    <si:thread-pool-task-executor id="taskPoolExecutor" max-size="4" />

    <si:channel id="channelOut">
    <si:queue capacity="12" />
    </si:channel>

    <si:chain id="primaryAdaptorChain" input-channel="routerOtherProf"
    output-channel="channelOut">
    <si:header-enricher error-channel="channelOut">
    <si:header name="serverInstance" value="ServerB" />
    </si:header-enricher>
    <si:service-activator ref="serviceInvoker" method="getAnonymousQuotes" />
    </si:chain>

    <si:chain id="secondaryAdaptorChain" input-channel="routerOtherProf"
    output-channel="channelOut">
    <si:header-enricher error-channel="channelOut">
    <si:header name="serverInstance" value="ServerB" />
    </si:header-enricher>
    <si:service-activator ref="serviceInvoker" method="getAnonymousQuotes" />
    </si:chain>


    Now in the service method i.e getAnonymousQuote it calls 3 different method, below is a simplified version of getAnonymousQuote Method

    public VQuote getAnonymousQuotes(MsgPayLoad params)
    {
    VQuote vq = null;;
    SomeHelper helper = new SomeHelper();

    Quote q = helper.createQuote(params); // this method takes 2secs

    vq = helper.rateQuote(params, q, vq); // this method takes 3 secs
    vq.setSomeParameter("Geek");

    if(vq.isValidate()){

    List elements = helper.getElements(params, vq);// this method takes 13secs
    vq.setElements(elements); // I can also do this in the getElements method.

    }
    return vq;
    }

    The main class sends at leaset 12 request (message Channels), which access this getAnonymousQuotes method parallely.
    Now when i try to retrieve this 12 response from Pollable channel, I see that there are couple of VQuote (vq) objects which has same element values.

    Why is it so? Even the occurance is mainly for the first2 request. I am not sure what is happening internally.

    Please please, try to give your expert comment as soon as possible.


    Couple of more querry,
    I think there is a single instance created for the Sevice Activator class, what if multiple threads are trying to access the service menthod getAnonymousQuotes parallely ?
    Last edited by Paresh; Sep 7th, 2010, 03:04 AM.

  • #2
    Is your service class is scoped as 'singleton' which is the default? and is that what you want?

    Comment


    • #3
      My Basic requirement is parallel executing the service method without hampering performance. as of now my Service Activator class is singleton.
      But multiple threads modifies the VQ object & I am not sure how it is working internally.

      I would like to know how can I invoke service class parallely making sure that the VQ object is altered by its thread only.

      Comment


      • #4
        We already established that your service is a singleton which means any instance variable in a multi-threaded environment is subject to a race condition. My question is is your service designed for multi-threaded environment?
        If not then scope a bean as 'prototype'.

        Comment


        • #5
          Thanks oleg for your quick reply. I have tried making the service bean scope as prototype.
          but still it only creates 2 instance since there are 2 chains. But in my case there are more the 5 mesaages being send.
          If you mean using synchronization then I think My service is not designed for the mutlti-threaded enviorment. The above piece of code is exactly same replica code. which does
          not use any sunchronization.
          If I use synchronization on VQ object as per above code then it behaves like a sequential calls, which is not what I want :-(

          I want multiple threads atleast 2-3 threads should execute the getAnonymousQuotes method with its own set of independent data. which will make sure that there is parallel execution which will reduce my execution time significantly.

          Oleg hope you understood my requirement. please let me know if you any questions
          Last edited by Paresh; Sep 7th, 2010, 10:34 AM.

          Comment


          • #6
            Any update ???

            Comment


            • #7
              Hii i m new to this community

              Hii
              I m new to this community pls tell me the way to create a new thread(post) complete link details as i have a query regarding spring transaction management though TransactionProxyFactoryBean.

              Comment


              • #8
                Hi Tikendra,

                If the post is regarding Spring Integration than go to this link http://forum.springsource.org/forumdisplay.php?f=42 & click
                "New Thread" Button.
                else you can go to
                http://forum.springsource.org/forumdisplay.php?f=21 & see the projects & create a new
                thread accordingly

                Comment


                • #9
                  Task Pool Executor with a max poolsize of 4 is creating many threads

                  I think it is creating new thread for each request (not sure ). Can we get to know how can we kill the previous threads ?

                  <si:channel id="inputChannelIn">
                  <si:dispatcher load-balancer="round-robin" failover="true"
                  task-executor="taskPoolExecutor" />
                  </si:channel>

                  <si:thread-pool-task-executor id="taskPoolExecutor" max-size="5" />

                  Not only that the behaviour is very wierd
                  I am too much worried about this.

                  Please please reply as soon as possible.

                  Comment


                  • #10
                    One Important Question. Are the Direct channel or any other Channel Singleton ?

                    I am having multiple thread which is invoking a method from a Singleton Class. (that means same code is executed every time). Now if the input Channel is Singleton than it will use the same input channel for each call
                    which is not what I want.

                    Comment


                    • #11
                      Hi Paresh,
                      There are 2 issues in your post as i see.
                      1) Why there are couple of vq objects with same elements?
                      2) How can you make your service method run parallely.

                      Before answering any of your questions getting to know how task pool executor is working is essential for you to solve your issues,

                      For each message that is put on channel 'inputChannelIn', there will be a new thread created which then dispatches to two subscribers 'primaryAdaptorChain' and 'secondaryAdaptorChain'. These two subscribers will then put the message output which has VQuote object as your payload in your 'channelOut' queue. As your 'channelOut' is buffering queue, as long as there is room in it, your task executor thread will be killed at this point or they will be blocked if your queue is full.

                      I didn't answer your questions, but i thought clarifying how your task executor is working will help you take it from here and debug it further.

                      If i were you, i would debug the code by
                      a) Have just one subscriber
                      b) or, change your 'inputChannelIn' a DirectChannel
                      c) Making sure that your Service class has truly a multi-thread safe method.
                      --sri


                      Originally posted by Paresh View Post
                      Task Pool Executor with a max poolsize of 4 is creating many threads

                      I think it is creating new thread for each request (not sure ). Can we get to know how can we kill the previous threads ?

                      <si:channel id="inputChannelIn">
                      <si:dispatcher load-balancer="round-robin" failover="true"
                      task-executor="taskPoolExecutor" />
                      </si:channel>

                      <si:thread-pool-task-executor id="taskPoolExecutor" max-size="5" />

                      Not only that the behaviour is very wierd
                      I am too much worried about this.

                      Please please reply as soon as possible.

                      Comment


                      • #12
                        Firstly, I would like to thank Srikondoji for replying to my post thread.

                        1) Why there are couple of vq objects with same elements?
                        Ans: VQ object will never have same elements since the below code takes VQ as input parameter which is always different for each request.

                        List elements = helper.getElements(params, vq);// this method takes 13secs
                        vq.setElements(elements); // I can also do this in the getElements method.

                        The elements are being fetched based on the vq object i.e say some primary key in Vq object (lets say quoteSeqNo). so always each vq will have different quoteSeqNo (assumption if multiple threads are not accessing the same VQ object).

                        2) How can you make your service method run parallely.
                        Ans: there are multiple users (approximately 20-30 users) who are trying to invoke the service method (exposed using Http remoting in spring). the Service Class is singleton which creates instance of the Message (Payloads) & send the message over input channel (id="routerOtherProf") which is a Direct Channel. So as stated earlier for 1 user there are min 12 Messages created & placed on the input Direct channel which invokes the serviceActivator's getAnonymousQuotes(..) method.

                        Hope I have answered your question

                        Now coming to rest of the post.: Thanks for the explanation for the task executor.

                        I am already using Direct Channel as an input channel.
                        Having one subscriber gives me very wierd results because there are multiple thread (input channel threads) which are accessing the method Tried putting sysouts which printed that each thread is getting the same instance of service Activator class even after using the scope ="prototype" for the serviceInvoker bean used in serviceActivator.

                        synchronizing the getAnonymousQuotes method makes it a sequential call. which takes more time (an obvious behaviour).

                        Also if you note the getAnonymousQuotes(..) method all the variables are local variables(method variables) & every time we create a inew nstance of helper class so that no 2 threads access the same instance.

                        Please do let me know if you need more information.

                        Comment


                        • #13
                          I do not see your actual code, but my guess is, that the 'quoteSeqNo' generation is not threadsafe, so the same id is generated in different threads, and after that the same vq object is generated.

                          This or, other not threadsafe operation in your code might cause your problem.

                          Comment


                          • #14
                            Logs does not show that kind of behaviour so I think its not true
                            Also as I said every time a new instance is created for helper class & this VQ object is created locally so the behaviour is something like this :

                            Thread1 --> Service Activator(SA) 1(instance1) method --> Helper (instance1).method{ which is creating VQ object & returning it back}

                            Thread2 --> Service Activator(SA) 2(instance2) method --> Helper (instance2).method{ which is creating VQ object & returning it back}

                            Thread3 --> Service Activator(SA) 3(instance3) method --> Helper (instance3).method{ which is creating VQ object & returning it back}

                            Thread4 --> Service Activator(SA) 4(instance4) method --> Helper (instance4).method{ which is creating VQ object & returning it back}

                            I think this can happen only if

                            Thread5 --> Service Activator(SA) 1(instance1) method --> Helper (instance1).method{ which is creating VQ object & returning it back}


                            Thread --- resembles thread for each message on inputDirectChannel.
                            Service Activator --- has a ref bean which has scope = prototype
                            Helper --- is a class whose new instance is created in the service method of the SA Helper h = new Helper();

                            Please let me know if you need more information.

                            Comment


                            • #15
                              Can you explain why you don't want the channel to be a singleton?

                              Keep in mind that a channel is just connecting a sender to a handler. It's most likely the handler about whose scope you should be concerned.

                              -Mark

                              Comment

                              Working...
                              X