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

  • Regarding CachingTcpConnectionFactory

    Hi


    I am tring to implement a connection pool for tcp connections.


    I went through the CachingTcpConnectionFactory on

    https://github.com/garyrussell/sandb...onFactory.java


    So I am doing this post just for clarify some questions.

    Code:
    <int-ip:tcp-connection-factory id="client"
    		deserializer="deserializer" type="client" host="${socket.host}"
    		port="${socket.port}" so-timeout="60000" />
    
    <bean id="caching" class="com.infrastructure.connection.CachingTcpConnectionFactory">
    	<constructor-arg ref="client" />
    	<property name="poolSize" value="10" />
    	<property name="availableTimeout" value="10000"/>
    	
    	</bean>
    
    
    
    	<int-ip:tcp-outbound-gateway id="outGateway"
    		request-channel="sendStringMessageChannel" reply-channel="recieveStringMessageChannel"
    		connection-factory="caching" request-timeout="10000" reply-timeout="10000" />


    If I am using the tcp-outbound-gateway instead of adapters is there any way to get the response if I returned the CachedConnection object which extends AbstractTcpConnectionInterceptor?

    Do I have to register the sender and listner for the CachedConnection object?

    Could you please guide me on this.


    But with out returning the CachedConnection object I just return the TcpConnection object and I was able to get the response.

    I cannot figure out how to overide the close() to add used connections to the available BlockingQueue and removed from the inUse Set if Im not returning a CachedConnection object which extends AbstractTcpConnectionInterceptor

    So is there any way to overide the close() while using the tcp-outbound-gateway ?


    Thanks in advance for any explanation on this.

  • #2
    That was a prototype I wrote a long time ago; I was going to point you to the current implementation in 2.2 which will be out shortly (2.2.0.RC3 was released last week).

    However, I see that the same problem occurs there too.

    I have opened a bug: https://jira.springsource.org/browse/INT-2839

    I'll work on it today.

    Comment


    • #3
      I really appreciate your help. Thanks a lot.

      Comment


      • #4
        I have fixed the problem with the (now) standard caching connection factory in the 2.2 master branch

        https://github.com/SpringSource/spri...ation/pull/686

        The same technique MIGHT work with that old prototype in my sandbox, but I would recommend you try with 2.2.0.BUILD-SNAPSHOT; barring any final hiccups, we are planning to release 2.2.0.RELEASE in the next day or so.

        Comment


        • #5
          Thanks.

          I was able to implement the connection pool using CachingClientConnectionFactory.


          This is the configurations that I used.



          Code:
          <int-ip:tcp-connection-factory id="tcpConnectionFactory"
          		deserializer="deserializer" type="client" host="${socket.host}"
          		port="${socket.port}" so-keep-alive="true"/>
          
          	<int-ip:tcp-outbound-gateway id="outboundGateway"
          		request-channel="sendStringMessageChannel" reply-channel="recieveStringMessageChannel"
          		connection-factory="tcpConnectionPool" request-timeout="10000"
          		reply-timeout="10000" />
          
          	<bean id="tcpConnectionPool"
          		class="org.springframework.integration.ip.tcp.connection.CachingClientConnectionFactory">
          		<constructor-arg ref="tcpConnectionFactory" />
          		<constructor-arg type="int"
          			value="50" />
          	</bean>
          
          	<bean id="deserializer"
          		class="com.infrastructure.connection.SocketInputStreamDeserializer" />


          But I am experiencing an issue when using the app after a long idle time.



          Code:
          Caused by: java.net.SocketException: Broken pipe
                  at java.net.SocketOutputStream.socketWrite0(Native Method)
                  at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
                  at java.net.SocketOutputStream.write(SocketOutputStream.java:141)
                  at org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer.serialize(ByteArrayCrLfSerializer.java:74)
                  at org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer.serialize(ByteArrayCrLfSerializer.java:31)
                  at org.springframework.integration.ip.tcp.connection.TcpNetConnection.send(TcpNetConnection.java:70)
                  at org.springframework.integration.ip.tcp.connection.AbstractTcpConnectionInterceptor.send(AbstractTcpConnectionInterceptor.java:122)
                  at org.springframework.integration.ip.tcp.TcpOutboundGateway.handleRequestMessage(TcpOutboundGateway.java:121)
                  ... 92 more


          Thanks in advance for any guidance related to this.

          Comment


          • #6
            Interesting; the so-keep-alive should cause the broken connection to be detected and, whenever we get a connection from the pool we check it's still open before handing it out.

            I suppose there might be a race condition, depending on when the close happens.

            You could add a retry advice to the outbound gateway to try again when this occurs.

            http://static.springsource.org/sprin...r-advice-chain

            Comment


            • #7
              Hi

              Thanks a lot for your quick response.

              If I do not set the so-keep-alive property what will happen?

              Comment


              • #8
                It depends on the network and exactly who/what is closing the connection.

                If the server closes the connection, the client should always be told. However, if a switch/proxy simply drops the connection, or the server has a power failure, the client isn't told until he tries to send a message - keep alives are intended to avoid such situations - enabling the client to learn that a connection is dead. The actual keepalive behavior (how often they are sent etc) is configured by the operating system/tcp stack.

                Comment


                • #9
                  OK. I'll work on the previous solution and will get back to you on tomorrow.

                  Thanks.

                  WISH YOU A HAPPY NEW YEAR

                  Comment


                  • #10
                    Hi

                    I had add a retry advice and tested the app.So far I didn't get the broken pipe exception.

                    This is the configurations that I used.


                    Code:
                    <int-ip:tcp-connection-factory id="tcpConnectionFactory"
                    		deserializer="deserializer" type="client" host="${socket.host}"
                    		port="${socket.port}" so-keep-alive="true"/>
                    
                    	<int-ip:tcp-outbound-gateway id="outboundGateway"
                    		request-channel="sendStringMessageChannel" reply-channel="recieveStringMessageChannel"
                    		connection-factory="tcpConnectionPool" request-timeout="10000"
                    		reply-timeout="10000" />
                    
                    	<int:service-activator input-channel="input" ref="retryFailer"
                    		method="service">
                    		<int:request-handler-advice-chain>
                    			<bean
                    				class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
                    				<property name="recoveryCallback">
                    					<bean
                    						class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
                    						<constructor-arg ref="connectionRetyErrorChannel" />
                    					</bean>
                    				</property>
                    			</bean>
                    		</int:request-handler-advice-chain>
                    	</int:service-activator>
                    
                    	<bean id="retryFailer"
                    		class="com.infrastructure.connection.ConnectionRetry" />
                    
                    
                    	<bean id="tcpConnectionPool"
                    		class="org.springframework.integration.ip.tcp.connection.CachingClientConnectionFactory">
                    		<constructor-arg ref="tcpConnectionFactory" />
                    		<constructor-arg type="int"
                    			value="50" />
                    	</bean>
                    
                    	<bean id="deserializer"
                    		class="com.infrastructure.connection.SocketInputStreamDeserializer" />



                    Thanks a lot for your guidance.

                    Comment

                    Working...
                    X