Announcement Announcement Module
Collapse
No announcement yet.
Pooling target sources Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Pooling target sources

    Hi all,

    Reading the reference documentation (version 1.0.2) on the subject I miss some examples that would provide guidance on the expected usage pattern, when exactly are beans released to the pool, etc.

    I have tried a simple example and it seems I am always getting the same instance.

    Also, I tried using the "poolConfigAdvisor" bean as illustrated in the reference documentation (page 53) but got the following exception:

    org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'poolConfigAdvisor' defined in file [C:\development\springaoptest1\springconfig-pool.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'target' of bean class [org.springframework.beans.factory.config.MethodInv okingFactoryBean]: Property 'target' is not writable
    ...

    Of course, as I am a complete newbie to Spring I may be doing hundreds of things wrong... :?

    Thanks,
    Fernando

  • #2
    Fernando

    Pooling behaviour is quite hard to test, as it's perfectly valid to get the same instance in successive calls in the same thread.

    An object will be obtained from the pool when the AOP framework creates the MethodInvocation object, when the method call hits an advised object. The object will be released from the pool when the method call is completed, whether it returns successfully or throws an exception.

    The usage pattern should be like that of stateless session beans. You will have a pool of objects that each can maintain configuration (populated by DI in the case of Spring pooling) but cannot maintain state on behalf of clients. Think hard about why you want pooling at all and can't have a single thread safe instance.

    The issue with the config advisor is an error in the documentation. It should be "targetObject". Thanks for pointing this out--I've fixed it.

    Rod

    Comment


    • #3
      Mr. Johnson,

      Thank you very much for your prompt answer!

      Changing property "target" to "targetObject" did the trick (as I should have known if taken the time to read MethodInvokingFactoryBean's api documentation).

      Regarding the reason for pooling: I do have in fact an unusual scenario where the pooled bean would have an embedded rhino JavaScript engine. This engine maintains quite a lot of state (on behalf of all clients) and thus is quite expensive to create. During a method call some state is created to handle that client call and then it is discarded to avoid any side-effects. Unfortunately that state (the top-most parent scope for js variables) has to be associated to the engine in a non thread-safe manner.

      Best regards,
      Fernando

      Comment


      • #4
        Scripting

        Fernando

        This does sound like a good reason for pooling.

        Your work with scripting also sounds interesting. I have put some Groovy integration in the sandbox, which allows any bean to be coded in Groovy, and the script changed at runtime. The approach also works for beanshell. Is this similar to your motivation with Rhino/JS?

        R

        Comment


        • #5
          Scripting (and Yet Another Framework horror)

          Rod

          Yes, that's exactly the motivation.

          Actually these "rhino engines" I mentioned are part of an internally used J2EE framework I developed a few years ago for the company I work for. Although the framework (called BCF) is being actively used and maintained, I am beginning to look hard into Spring for several reasons:
          1. Spring's goals are very similar to BCF's.
          2. Spring IS MUCH BETTER.
          3. Looking forward, I'd rather contribute to a well known, successful and architecturally sound framework such as Spring than to a closed-source effort. Even if it is mine!

          F

          Comment


          • #6
            Scripting

            Fernando

            Please take a look at the Groovy support in the sandbox, to see if your approach could fit in with it.

            The best place to look is the tests, which show how it's set up. By default it will detect modifications of script files, configured by a timeout. The package is org.springframework.beans.factory.groovy.

            To support a different language, you need only to implement a script class and a subclass of AbstractScriptFactory. There were only about 30 lines of code in bsh support, which I haven't committed because I didn't want to add a bsh dependency at this point.

            I'm keen on using scripts for web app controllers. I think with a clean separation of web tier and business objects, as I advocate in both books, it's arguably a best practice to use a scripting language in web controllers.

            Probably about time we took this discussion to the dev list, or continued it via email

            Rgds
            Rod

            Comment


            • #7
              Originally posted by Rod Johnson
              Fernando

              Pooling behaviour is quite hard to test, as it's perfectly valid to get the same instance in successive calls in the same thread.

              An object will be obtained from the pool when the AOP framework creates the MethodInvocation object, when the method call hits an advised object. The object will be released from the pool when the method call is completed, whether it returns successfully or throws an exception.

              The usage pattern should be like that of stateless session beans. You will have a pool of objects that each can maintain configuration (populated by DI in the case of Spring pooling) but cannot maintain state on behalf of clients. Think hard about why you want pooling at all and can't have a single thread safe instance.

              The issue with the config advisor is an error in the documentation. It should be "targetObject". Thanks for pointing this out--I've fixed it.

              Rod
              My idea about the Pooling would be the Performance improvement , typically if the Object is being frequently used . Let us call this a caching of the object , as the concurrent user access increases for a particular objects , here I would assume a typical applicaiton where each client invovation spans a thread and they all are accessing an common Object .
              Originally posted by Case 1:
              If there are limited number of clients accessing then we can afford object creation as per the Thread needs .So there is not caching of the object .
              Originally posted by Case 2:
              If the concurrent users increase then you have the application performance being affected , so we can cache a single instance and proceed , I will keep the case simple that the object does not maintan a state .
              Originally posted by Case 3:
              The concurrent users increses more , which can lead to substantial Context Switching which can affect the performance , so we can cache now multiple objects , ya the object pooling .
              Referring to above cases I would say , the decision of pooling can be done at the design or while at the Applicaition Tuning Stage ..
              There can be many more combination , if we consider the object to store the state .
              It can be tough descision to decide on pooling if we start thinking of minute details .

              Regards
              Vicky

              Comment


              • #8
                Vicky, thank you for the info.

                Regards,
                F

                Comment


                • #9
                  Don't quite understand the single instance explanation...

                  Mr. Johnson-
                  I'm not sure I get the explantion you gave initially about the validity of getting the same instance from a pool of objects that, particularly n the case I've listed below. Could you clarify?

                  Also in regards to your comment:

                  An object will be obtained from the pool when the AOP framework creates the MethodInvocation object, when the method call hits an advised object. The object will be released from the pool when the method call is completed, whether it returns successfully or throws an exception.
                  Does this mean that this implementation of pooling (Ref Documentation v.1.1.4 Section 5.11.2. Pooling target sources) does not work for objects that are not advised? Despite this graph from the section?

                  In this case, "myInterceptor" is the name of an interceptor that would need to be defined in the same IoC
                  context. However, it isn't necessary to specify interceptors to use pooling. If you want only pooling, and no
                  other advice, don't set the interceptorNames property at all.
                  Code:
                  	<bean id="pooledCarTarget" class="com.savan.beans.PooledCar" singleton="false"/>
                  	<bean id="pooledCarSource" class="org.springframework.aop.target.CommonsPoolTargetSource">
                  		<property name="targetBeanName">
                  			<value>pooledCarTarget</value>
                  		</property>
                  		<property name="maxSize">
                  			<value>5</value>
                  		</property>
                  	</bean>
                  	<bean id="pooledCar" class="org.springframework.aop.framework.ProxyFactoryBean">
                  		<property name="targetSource">
                  			<ref local="pooledCarSource" />
                  		</property>
                  	</bean>
                  Code:
                      public void testPoolLimit&#40;&#41; &#123;
                          List carPool = new ArrayList&#40;&#41;;
                  
                          CommonsPoolTargetSource pool =
                              &#40;&#40;CommonsPoolTargetSource&#41;factory.getBean&#40;"pooledCarSource"&#41;&#41;;
                          assertTrue&#40;pool.getMaxSize&#40;&#41; == 5&#41;;
                  
                          for &#40;int i = 0; i <= 10; i++&#41; &#123;
                              PooledCar car = &#40;PooledCar&#41;factory.getBean&#40;"pooledCar"&#41;;
                              carPool.add&#40;car&#41;;
                          &#125;
                  
                          assertTrue&#40;carPool.size&#40;&#41; < 10&#41;;
                      &#125;
                  Thanks in advance-
                  Savan Thongvanh

                  Comment


                  • #10
                    My idea about the Pooling would be the Performance improvement , typically if the Object is being frequently used . Let us call this a caching of the object , as the concurrent user access increases for a particular objects , here I would assume a typical applicaiton where each client invovation spans a thread and they all are accessing an common Object .
                    If the object doesn't hold state--and service objects typically don't--there is no limit to the number of threads that can hit it concurrently. No contention. No limitations to throughput whatsoever. In fact, the single instance in this case will always outperform a pool (by a small margin, if the pool is well implemented and the pool size is correct).

                    Comment


                    • #11
                      Does this mean that this implementation of pooling (Ref Documentation v.1.1.4 Section 5.11.2. Pooling target sources) does not work for objects that are not advised?
                      You must advise objects to have pooling. This can be done with an auto proxy creator, so you don't need much config. However, you do not need interceptors. So the advising can consist just of the pooling target source, with no other crosscutting behaviour.

                      Comment


                      • #12
                        If I understand correctly, Spring's pool will "lend" me an object from the pool when I hit a method, and will automatically return the object to the pool when the method execution ends.

                        This behaviour is problematic in the case of a Thread, in the case I want a pool of threads, since the method execution will end immediatly:

                        A is pooled (it creates a thread in the init method).
                        B gets A from the pool (transparently using AOP)
                        B starts A.run() (A.run returns immediatly, so Spring returns A to the pool, but the thread is still running in the background)
                        C gets A from the pool (it gets the same instance as B).
                        C starts A.run()
                        Now A.run() throws an IllegalStateException.

                        I've found this problem in an app I'm woring on, and I think that a valid solution is JDK1.5's concurrency utils (AFAIK there's a backport to 1.4).

                        Am I doing something wrong ?

                        Regards,
                        Esteve

                        Comment


                        • #13
                          Yes, it wasn't really designed to pool threads, but to do the same kind of thing stateless session beans do.

                          Comment

                          Working...
                          X