You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Amitava Chakraborty <am...@in.ibm.com> on 2008/01/25 05:03:04 UTC

Error encountered : JNDI on Tomcat 5.5 for Database Informix with Informix JDBC driver

Hi All,

    I am from IBM - Informix Product Interoperability team .  I tried to
create a JNDI connection from Tomcat to Database Informix. But it is
throwing error. I classified the error by the following way :

1. When I tried with type="javax.sql.DataSource"  , I am getting error
"Cannot create PoolableConnectionFactory (Can't load driver
java.lang.reflect.InvocationTargetException)" .

2. When I tried with  type="com.informix.jdbcx.IfxConnectionPoolDataSource"
, I am getting error  "java.sql.SQLException: No suitable driver".

3. But we use JNDI connections from WAS , WAS CE and Web Logic also. There
it works fine.

4. Here I have added a sample Java Code also for Pooled connection and it
is working fine.

So the clarification I need is,  whether Tomcat supports Informix for a
JNDI connection. If yes, please suggest me the way it should work . I
attached my context.xml as well as web.xml contains also.

Looking for your help eagerly.

====================================================================================
Context File Entry:

              <Resource name="jdbc/myinformix" auth="Container"
type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="inform" password="inform123"
driverClassName="com.informix.jdbc.IfxDriver"

url="jdbc:informix-sqli://idcps2.in.ibm.com:16001/stores_demo:INFORMIXSERVER=ids1050"/>


WEB-INF\web.xml Entry:

<description>Informix Test Connection</description>
  <resource-ref>
      <description>Informix DB Connection</description>
      <res-ref-name>jdbc/myinformix</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>

type Exception report

message

description The server encountered an internal error () that prevented it
from fulfilling this request.

exception

org.apache.jasper.JasperException: Unable to get connection, DataSource
invalid: "org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create
PoolableConnectionFactory (Can't load driver
java.lang.reflect.InvocationTargetException)"

org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:460)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:355)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

javax.servlet.ServletException: Unable to get connection, DataSource
invalid: "org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create
PoolableConnectionFactory (Can't load driver
java.lang.reflect.InvocationTargetException)"

org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:841)

org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:774)

org.apache.jsp.Informix.test_005fconnection_jsp._jspService(test_005fconnection_jsp.java:80)
      org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

javax.servlet.jsp.JspException: Unable to get connection, DataSource
invalid: "org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create
PoolableConnectionFactory (Can't load driver
java.lang.reflect.InvocationTargetException)"

org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.getConnection(Unknown
 Source)

org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.doStartTag(Unknown
 Source)

org.apache.jsp.Informix.test_005fconnection_jsp._jspx_meth_sql_005fquery_005f0(test_005fconnection_jsp.java:99)

org.apache.jsp.Informix.test_005fconnection_jsp._jspService(test_005fconnection_jsp.java:57)
      org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)




===========================================================================================
Context File Entry:
<Resource name="jdbc/myinformix" auth="Container"
type="com.informix.jdbcx.IfxConnectionPoolDataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="inform" password="inform123"
driverClassName="com.informix.jdbc.IfxDriver"

url="jdbc:informix-sqli://idcps2.in.ibm.com:16001/stores_demo:INFORMIXSERVER=ids1050"/>

WEB-INF\web.xml Entry:

<resource-ref>
      <description>Informix DB Connection</description>
      <res-ref-name>jdbc/myinformix</res-ref-name>
      <res-type>com.informix.jdbcx.IfxConnectionPoolDataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>



Stacktrace:

org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:451)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:355)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

javax.servlet.ServletException: Unable to get connection, DataSource
invalid: "java.sql.SQLException: No suitable driver"

org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:841)

org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:774)

org.apache.jsp.Informix.test_005fconnection_jsp._jspService(test_005fconnection_jsp.java:82)
      org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

root cause

  javax.servlet.jsp.JspException: Unable to get connection, DataSource
invalid: "java.sql.SQLException: No suitable driver"

org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.getConnection(Unknown
 Source)

org.apache.taglibs.standard.tag.common.sql.QueryTagSupport.doStartTag(Unknown
 Source)

org.apache.jsp.Informix.test_005fconnection_jsp._jspx_meth_sql_005fquery_005f0(test_005fconnection_jsp.java:101)

org.apache.jsp.Informix.test_005fconnection_jsp._jspService(test_005fconnection_jsp.java:59)
      org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)

org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)

org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
      org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:803)


=======================================================================================================
Stand Alone Java Program works perfectly for a pooled connection

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.informix.jdbcx.IfxConnectionPoolDataSource;
import javax.sql.*;

public class test5
{
      IfxConnectionPoolDataSource cpds = null;

      public Connection getConnection () throws SQLException, Exception
      {

      cpds  = new IfxConnectionPoolDataSource();
      cpds.setUser("informix");
      cpds.setPassword("inform123");
      cpds.setServerName("ids1050");
      cpds.setDatabaseName("stores_demo");
      cpds.setPortNumber(16001);
      cpds.setIfxPROTOCOLTRACE(99);
      cpds.setIfxIFXHOST("idcps2.in.ibm.com");
      PooledConnection pooledCon = cpds.getPooledConnection();
      return pooledCon.getConnection();
      }

      void testinsert (Connection conn) throws SQLException
      {
          int rc ;
              String sql = "INSERT INTO TOMCAT_TEST VALUES ( 1, 'TEST') " ;

          try
          {
            PreparedStatement pstmt = conn.prepareStatement(sql);
            System.out.println("Executing the statement: " + sql);
          rc = pstmt.executeUpdate();
          System.out.println("Statement executed successfully with RC "+
rc);
            sql="select * from TOMCAT_TEST";
            pstmt = conn.prepareStatement(sql);
            ResultSet rs = pstmt.executeQuery();
              while (rs.next())
              {
                  System.out.println("After fetch the value is ID="
+rs.getString(1) + " CHAR "+ rs.getString(2) );
              }

          }
            catch (SQLException s)
            {
            printSQLException(s);
            System.out.println("Prepare Statement: " + s.toString());
            }

    }

    public void createTable (Connection conn) throws SQLException
      {
            String sql = "CREATE TABLE TOMCAT_TEST( ID_TOMCAT
INTEGER,ID_CHAR CHAR(12)) LOCK MODE ROW" ;
            Statement stmt = conn.createStatement();
            System.out.println("Creating the table TOMCAT_TEST ...");
            stmt.executeUpdate(sql);
            System.out.println("Table created successfully!");
      }

     public void dropTable (Connection conn) throws SQLException
      {
            String sql = "DROP TABLE TOMCAT_TEST";
            Statement stmt = conn.createStatement();

            try
            {
                System.out.println("Dropping the table TOMCAT_TEST ...");
                stmt.executeUpdate(sql);
                System.out.println("Table dropped successfully!");
            }
            catch (SQLException exc)
            {
                  if (exc.getSQLState().equals("42000"))
                  {
                        System.out.println("The table, dbuser1.user1, does
not exist in the database.");
                        System.out.println("Skip dropping the table.");
                  }
                  else
                  {
                      printSQLException(exc);
                      throw exc;
                  }
            }
       }



    public static void printSQLException (SQLException exc)
    {
            if (exc != null)
            {
                System.out.println("Error Code: " + exc.getErrorCode());
                System.out.println("SQL State: " + exc.getSQLState());
                System.out.println("Message: " + exc.getMessage());
                exc.printStackTrace();
                printSQLException(exc.getNextException());
            }
            else
            {
                  return;
            }
      }

    public static void main (String[] args)
    {
      test5 test = new test5();
            try
            {
                  Connection conn = test.getConnection();
                  test.dropTable(conn);
                  test.createTable(conn);
                  test.testinsert(conn);

            }
            catch (Exception exc)
            {
                  exc.printStackTrace();
            }
      }

}

Thanks..
Amitava Chakraborty  PMP®
Lead - Informix Interoperability
IBM India PVT LTD.
Plot No 1&2, Block - G, 2nd Floor ,
The Mira Corporation Suites, Old Ishwar Nagar,
Mathura Rd.       New Delhi 110065
-------------------------------------------
Ph : Extn : 91-11-46592644 / 91-129-4033409
Mobile : +919958995870
Fax : 91-11-26921061
E - id : amitacha@in.ibm.com


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Error encountered : JNDI on Tomcat 5.5 for Database Informix with Informix JDBC driver

Posted by Gabe Wong <ga...@ngasi.com>.
Amitava Chakraborty wrote:
> Gabe,
>
> Informix JDBC jars (ifxjdbc.jar , ifxjdbcx.jar) are already there under
> ./common/lib/
>
>   

Bunch of other things:
I assume you are not adding classpath to Tomcat startup script?
And it is a distro directly from tomcat.apache.org
And of course not a GNU (linux distro) JDK

> Thanks..
> Amitava Chakraborty  PMP®
> Lead - Informix Interoperability
> IBM India PVT LTD.
> Plot No 1&2, Block - G, 2nd Floor ,
> The Mira Corporation Suites, Old Ishwar Nagar,
> Mathura Rd.       New Delhi 110065
> -------------------------------------------
> Ph : Extn : 91-11-46592644 / 91-129-4033409
> Mobile : +919958995870
> Fax : 91-11-26921061
> E - id : amitacha@in.ibm.com
>
>
>                                                                            
>              Gabe Wong                                                     
>              <gabrielw@ngasi.c                                             
>              om>                                                        To 
>                                        Tomcat Users List                   
>              25/01/2008 11:13          <us...@tomcat.apache.org>           
>                                                                         cc 
>                                                                            
>              Please respond to                                     Subject 
>                "Tomcat Users           Re: Error encountered : JNDI on     
>                    List"               Tomcat 5.5 for Database Informix    
>              <users@tomcat.apa         with Informix JDBC driver           
>                  che.org>                                                  
>                                                                            
>                                                                            
>                                                                            
>                                                                            
>                                                                            
>
>
>
>
> Amitava Chakraborty wrote:
>   
>> Hi All,
>>
>>     I am from IBM - Informix Product Interoperability team .  I tried to
>> create a JNDI connection from Tomcat to Database Informix. But it is
>> throwing error. I classified the error by the following way :
>>
>> 1. When I tried with type="javax.sql.DataSource"  , I am getting error
>> "Cannot create PoolableConnectionFactory (Can't load driver
>> java.lang.reflect.InvocationTargetException)" .
>>
>> 2. When I tried with
>>     
> type="com.informix.jdbcx.IfxConnectionPoolDataSource"
>   
>> , I am getting error  "java.sql.SQLException: No suitable driver".
>>
>> 3. But we use JNDI connections from WAS , WAS CE and Web Logic also.
>>     
> There
>   
>> it works fine.
>>
>>     
>
> You need to add the driver under ./common/lib/
> More info can be found here:
> http://marc.info/?l=tomcat-user&w=2&r=1&s=No+suitable+driver&q=b
>
> --
> Regards
>
> Gabe Wong
> NGASI AppServer Manager
> JAVA AUTOMATION and SaaS Enablement
> <a href=http://www.ngasi.com>http://www.ngasi.com</a>
> NEW! 8.0 - Centrally manage multiple physical servers
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>
>
>   


-- 
Regards

Gabe Wong
NGASI AppServer Manager
JAVA AUTOMATION and SaaS Enablement
<a href=http://www.ngasi.com>http://www.ngasi.com</a>
NEW! 8.0 - Centrally manage multiple physical servers


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Error encountered : JNDI on Tomcat 5.5 for Database Informix with Informix JDBC driver

Posted by Amitava Chakraborty <am...@in.ibm.com>.
Gabe,

Informix JDBC jars (ifxjdbc.jar , ifxjdbcx.jar) are already there under
./common/lib/

Thanks..
Amitava Chakraborty  PMP®
Lead - Informix Interoperability
IBM India PVT LTD.
Plot No 1&2, Block - G, 2nd Floor ,
The Mira Corporation Suites, Old Ishwar Nagar,
Mathura Rd.       New Delhi 110065
-------------------------------------------
Ph : Extn : 91-11-46592644 / 91-129-4033409
Mobile : +919958995870
Fax : 91-11-26921061
E - id : amitacha@in.ibm.com


                                                                           
             Gabe Wong                                                     
             <gabrielw@ngasi.c                                             
             om>                                                        To 
                                       Tomcat Users List                   
             25/01/2008 11:13          <us...@tomcat.apache.org>           
                                                                        cc 
                                                                           
             Please respond to                                     Subject 
               "Tomcat Users           Re: Error encountered : JNDI on     
                   List"               Tomcat 5.5 for Database Informix    
             <users@tomcat.apa         with Informix JDBC driver           
                 che.org>                                                  
                                                                           
                                                                           
                                                                           
                                                                           
                                                                           




Amitava Chakraborty wrote:
> Hi All,
>
>     I am from IBM - Informix Product Interoperability team .  I tried to
> create a JNDI connection from Tomcat to Database Informix. But it is
> throwing error. I classified the error by the following way :
>
> 1. When I tried with type="javax.sql.DataSource"  , I am getting error
> "Cannot create PoolableConnectionFactory (Can't load driver
> java.lang.reflect.InvocationTargetException)" .
>
> 2. When I tried with
type="com.informix.jdbcx.IfxConnectionPoolDataSource"
> , I am getting error  "java.sql.SQLException: No suitable driver".
>
> 3. But we use JNDI connections from WAS , WAS CE and Web Logic also.
There
> it works fine.
>

You need to add the driver under ./common/lib/
More info can be found here:
http://marc.info/?l=tomcat-user&w=2&r=1&s=No+suitable+driver&q=b

--
Regards

Gabe Wong
NGASI AppServer Manager
JAVA AUTOMATION and SaaS Enablement
<a href=http://www.ngasi.com>http://www.ngasi.com</a>
NEW! 8.0 - Centrally manage multiple physical servers


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org




---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Error encountered : JNDI on Tomcat 5.5 for Database Informix with Informix JDBC driver

Posted by Gabe Wong <ga...@ngasi.com>.
Amitava Chakraborty wrote:
> Hi All,
>
>     I am from IBM - Informix Product Interoperability team .  I tried to
> create a JNDI connection from Tomcat to Database Informix. But it is
> throwing error. I classified the error by the following way :
>
> 1. When I tried with type="javax.sql.DataSource"  , I am getting error
> "Cannot create PoolableConnectionFactory (Can't load driver
> java.lang.reflect.InvocationTargetException)" .
>
> 2. When I tried with  type="com.informix.jdbcx.IfxConnectionPoolDataSource"
> , I am getting error  "java.sql.SQLException: No suitable driver".
>
> 3. But we use JNDI connections from WAS , WAS CE and Web Logic also. There
> it works fine.
>   

You need to add the driver under ./common/lib/
More info can be found here:
http://marc.info/?l=tomcat-user&w=2&r=1&s=No+suitable+driver&q=b

-- 
Regards

Gabe Wong
NGASI AppServer Manager
JAVA AUTOMATION and SaaS Enablement
<a href=http://www.ngasi.com>http://www.ngasi.com</a>
NEW! 8.0 - Centrally manage multiple physical servers


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Need *faster* connection abort with mod_jk

Posted by Rainer Jung <ra...@kippdata.de>.
Hi Chris,

you are totally right. It was a little late yesterday :(

I updates the two patches. The only change is in jk_ajp_common.c. The 
flax call inside ajp_next_connection is replaced by the normal one, so 
no more change there and instead the normal one in ajp_reset_endpoint 
now is a flex one.

I overlokked the obvious fact, that the client error is non recoverable, 
so we don't close the connection in ajp_next_connection, but instead 
immediately abort the service until later done is called and regularly 
closes the connection in ajp_reset_enpoint.

The patch should be safe in the sense that I don't expect problems. It's 
a little to early to guarantee inclusion in the regular distribution though.

Let us know, if you deploy it into production, and if it solves your 
problem.

Regards,

Rainer

Chris Hut schrieb:
> Hi Rainer, thanks so much for the reply, this is looks like just what we
> need!
> 
> I tried your patch on 1.2.26 and unfortunately it did not quite work -
> still got the 30 second wait.  I dug a little deeper with some debugging
> code and it looks like, in the case of a client abort, the code goes
> through the old jk_shutdown_socket function (which forces linger to be
> set to true) instead of the new jk_flex_shutdown_socket.
> 
> Here's my log output, my additions preceded with "=====":
> 
> [Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
> ajp_process_callback::jk_ajp_common.c (1606): Writing to client aborted
> or client network problems
> [Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
> ajp_service::jk_ajp_common.c (2191): (worker1) sending request to tomcat
> failed (unrecoverable), because of client write error (attempt=1)
> [Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
> ajp_reset_endpoint::jk_ajp_common.c (695): ====== non-reusable endpoint,
> calling jk_shutdown_socket
> [Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
> jk_shutdown_socket::jk_connect.c (636): ====== in jk_shutdown_socket,
> calling jk_flex_shutdown_socket with linger set to TRUE
> [Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
> jk_flex_shutdown_socket::jk_connect.c (661): ====== linger is: 1
> 
> Experimenting some more, I found that if I changed line 695 in
> jk_ajp_common.c from:
> 
> jk_shutdown_socket(ae->sd, l);
> 
> To:
> 
> jk_flex_shutdown_socket(ae->sd, ae->linger, l);
> 
> Then it works perfectly.  But, I hesitate to deploy my own hacks to our
> production systems so if you could give this a once-over (and perhaps an
> updated patch file, if you have time) that would be fantastic.
> 
> Thanks again for the help!
> 
> Chris
> 
> -----Original Message-----
> From: Rainer Jung [mailto:rainer.jung@kippdata.de] 
> Sent: Friday, January 25, 2008 4:37 PM
> To: Tomcat Users List
> Subject: Re: Need *faster* connection abort with mod_jk
> 
> Hi Chris,
> 
> perfect, that makes sense! Yes, we are draining the backend connection
> before closing it down, and since in your case the backend is happy to
> go along and proceed streaming it's not just a question of capturing a
> few additional bytes.
> 
> Mladen Turk added the connection draining a while ago, so we might need
> to discuss the pros and cons. The URL you gave includes a nice
> description. In our case there is no pipelining and once we finished
> sending the request (including possible request body) to the backend,
> closing without draining should be save.
> 
> I made a patch, that should disable connection draining exactly if we
> got a write error when using the client connection. The patch is
> available at
> 
> http://people.apache.org/~rjung/mod_jk-dev/patches/jk_close_immediate_on
> _client_wr_error.patch
> 
> (for 1.2.27-dev) and
> 
> http://people.apache.org/~rjung/mod_jk-dev/patches/jk_close_immediate_on
> _client_wr_error-1_2_26.patch
> 
> (for 1.2.26)
> 
> If you want to test it, I would suggest using 1.2.26, because 1.2.27-dev
> is not well tested yet and there are quite some changes in it.
> 
> Have fun,
> 
> Rainer
> 
> Chris Hut schrieb:
>> Hi Rainer, thanks for the reply!
>>
>>> interesting use case :)
>> Just trying to keep things entertaining around here :)
>>
>>> are you writing something back during the wait time, or are you 
>>> simply
>> doing processing on the backend?
>>
>> Yes, the long-running process (video rendering) is also streaming the 
>> video bytes back to the client using outputStream.write().  It's this 
>> write (ultimately, to an org.apache.catalina.connector.OutputBuffer)
>> that throws the ClientAbortException, if the client is actually gone.
>>
>> So I figured out that JK is definitely holding open its connection 
>> Tomcat meaning Tomcat does not know to abort.  In desperation I 
>> searched for the number "30" (hoping for a constant) in the mod_jk 
>> source code, and found this in jk_connect.c:
>>
>> #ifndef MAX_SECS_TO_LINGER
>> #define MAX_SECS_TO_LINGER 30
>> #endif
>> ...
>> int jk_shutdown_socket(jk_sock_t s)
>> {
>>     ...
>>     do {
>>         /* Read all data from the peer until we reach "end-of-file"
>>          * (FIN from peer) or we've exceeded our overall timeout. If
> the
>>          * backend does not send us bytes within 2 seconds
>>          * (a value pulled from Apache 1.3 which seems to work well),
>>          * close the connection.
>>          */
>>         ... /* [reads bytes] */
>>     } while (difftime(time(NULL), start) < MAX_SECS_TO_LINGER); }
>>
>> Sockets and low-level network programming aren't my strong suit, but 
>> from searching around it sounds like this (lingering) is a common 
>> practice to ensure proper TCP communication - I found a bit more info
>> here: http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix
>>
>> Tomcat's Http11Connector has a connectionLinger attribute (which 
>> translates internally to a soLinger) which sounds like it does the 
>> same thing - except that it's disabled by default.
>>
>> So, does anybody know if there would be any detrimental impact to 
>> re-compiling mod_jk with MAX_SECS_TO_LINGER set lower, say, 10 seconds
> 
>> or 5?  Or even lower?
>>
>> Thanks again for the help!
>>
>> Chris
>>
>>
>> -----Original Message-----
>> From: Rainer Jung [mailto:rainer.jung@kippdata.de]
>> Sent: Friday, January 25, 2008 7:03 AM
>> To: Tomcat Users List
>> Subject: Re: Need *faster* connection abort with mod_jk
>>
>> Hi Chris,
>>
>> interesting use case :)
>>
>> mod_jk closes the backend connection as soon as the reply_timeout 
>> fires, or there is something to write back to the client and mod_jk 
>> detects, that the connection to the client can not be used any longer 
>> (browser stop, retry or click on another link).
>>
>> If the user ends waiting for the reply and you don't try to write 
>> something back, mod_jk won't detect that, because it sits there and 
>> waits for something to come back from the backend. So to reliably 
>> detect a browser stop, you need to actively use the connection. From 
>> you comments about the mod_jk log file, it seems, that you are 
>> actually doing this.
>>
>> Why doesn't Tomcat immediately throw the exception: I guess (wild 
>> guess), that it also only notices the closed mod_jk connection, if it 
>> tries to use it. If you are actually using it continuously we would 
>> have to investigate, why there is such a delay.
>>
>> So first question to get closer would be: are you writing something 
>> back during the wait time, or are you simply doing processing on the
> backend?
>> In this case (because I don't understand the client abort detection of
> 
>> mod_jk then): Can you reproduce the behaviour for a single request on 
>> a test system using JkLogLevel debug?
>>
>> Please make sure, that the clocks on the mod_jk system and on the 
>> Tomcat system are in sync.
>>
>> Regards,
>>
>> Rainer
>>
>> Chris Hut wrote:
>>> Hi all,
>>>
>>> We're using Apache 2.0.61 with mod_jk 1.2.25 and Tomcat 6.0.14.
>>>
>>> We have a simple (non-load-balanced) apache/tomcat configuration 
>>> using
>>> a single worker to forward requests from apache to tomcat.
>>> (workers.properties is below)
>>>
>>> Our problem is: Some client requests kick off an expensive, 
>>> long-running server-side process.  Often, the client will give up 
>>> (e.g. the user will navigate to a different browser page) before 
>>> completion, and we want to cancel the server-side process early if
>> possible.
>>> We use the ClientAbortException to easily set an "interrupted" flag 
>>> which our process monitors to see if it should abort.  When 
>>> connecting
>>> straight to the servlet using Tomcat only, this is very simple as the
> 
>>> exception is thrown immediately and the process dies right away.  
>>> This
>>> is what we hope for.
>>>
>>> When connecting via apache/mod_jk, though, it takes 30 seconds for 
>>> the
>>> exception to be thrown in Tomcat.  For efficientcy we'd love the 
>>> abort
>>> to happen immediately if possible.
>>>
>>> In the mod_jk.log file, we see this as soon as the client aborts
> (e.g.
>>> closes browser):
>>>
>>> [Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info] 
>>> ajp_process_callback::jk_ajp_common.c (1511): Writing to client 
>>> aborted or client network problems [Thu Jan 24 20:09:35.535 2008] 
>>> [2011:1094711648] [info] ajp_service::jk_ajp_common.c (1996):
>>> (worker1) request failed, because of client write error without 
>>> recovery in send loop attempt=0
>>>
>>> But it takes 30 seconds to see:
>>>
>>> [Thu Jan 24 20:10:05.641 2008] [2011:1094711648] [info] 
>>> jk_handler::mod_jk.c (2270): Aborting connection for worker=worker1
>>>
>>> Which corresponds exactly to the time when the ClientAbortException 
>>> is
>>> thrown in Tomcat.
>>>
>>> Given the exact nature of the timing involved (30 seconds) I'm 
>>> guessing/hoping this is an apache and/or JK timeout setting; however,
> 
>>> I can't find a property that would do what we require which is just 
>>> to
>>> kill the Tomcat connection faster if the end-user client closes the 
>>> connection on their side.
>>>
>>> Can anybody point me to a setting to tweak?  I did try using
>>> recovery_options=4 (which says, "close the connection to Tomcat, if 
>>> we
>>> detect an error when writing back the answer to the client 
>>> (browser)")
>>> but the behavior is unchanged.  I feel like changing the worker 
>>> timeouts is the wrong direction because the JK-to-Tomcat 
>>> communication
>>> is working just fine, we just need a way to propagate JK's 
>>> client-abort error to Tomcat faster!
>>>
>>> Thanks for your help!
>>>
>>> workers.properties:
>>>
>>> worker.list=worker1
>>> worker.worker1.type=ajp13
>>> worker.worker1.host=localhost
>>> worker.worker1.port=8009
>>> #worker.worker1.retries=4
>>>
>>> Chris

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Need *faster* connection abort with mod_jk

Posted by Chris Hut <ch...@onetruemedia.com>.
Hi Rainer, thanks so much for the reply, this is looks like just what we
need!

I tried your patch on 1.2.26 and unfortunately it did not quite work -
still got the 30 second wait.  I dug a little deeper with some debugging
code and it looks like, in the case of a client abort, the code goes
through the old jk_shutdown_socket function (which forces linger to be
set to true) instead of the new jk_flex_shutdown_socket.

Here's my log output, my additions preceded with "=====":

[Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
ajp_process_callback::jk_ajp_common.c (1606): Writing to client aborted
or client network problems
[Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
ajp_service::jk_ajp_common.c (2191): (worker1) sending request to tomcat
failed (unrecoverable), because of client write error (attempt=1)
[Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
ajp_reset_endpoint::jk_ajp_common.c (695): ====== non-reusable endpoint,
calling jk_shutdown_socket
[Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
jk_shutdown_socket::jk_connect.c (636): ====== in jk_shutdown_socket,
calling jk_flex_shutdown_socket with linger set to TRUE
[Fri Jan 25 19:40:18.516 2008] [7419:1147140448] [info]
jk_flex_shutdown_socket::jk_connect.c (661): ====== linger is: 1

Experimenting some more, I found that if I changed line 695 in
jk_ajp_common.c from:

jk_shutdown_socket(ae->sd, l);

To:

jk_flex_shutdown_socket(ae->sd, ae->linger, l);

Then it works perfectly.  But, I hesitate to deploy my own hacks to our
production systems so if you could give this a once-over (and perhaps an
updated patch file, if you have time) that would be fantastic.

Thanks again for the help!

Chris

-----Original Message-----
From: Rainer Jung [mailto:rainer.jung@kippdata.de] 
Sent: Friday, January 25, 2008 4:37 PM
To: Tomcat Users List
Subject: Re: Need *faster* connection abort with mod_jk

Hi Chris,

perfect, that makes sense! Yes, we are draining the backend connection
before closing it down, and since in your case the backend is happy to
go along and proceed streaming it's not just a question of capturing a
few additional bytes.

Mladen Turk added the connection draining a while ago, so we might need
to discuss the pros and cons. The URL you gave includes a nice
description. In our case there is no pipelining and once we finished
sending the request (including possible request body) to the backend,
closing without draining should be save.

I made a patch, that should disable connection draining exactly if we
got a write error when using the client connection. The patch is
available at

http://people.apache.org/~rjung/mod_jk-dev/patches/jk_close_immediate_on
_client_wr_error.patch

(for 1.2.27-dev) and

http://people.apache.org/~rjung/mod_jk-dev/patches/jk_close_immediate_on
_client_wr_error-1_2_26.patch

(for 1.2.26)

If you want to test it, I would suggest using 1.2.26, because 1.2.27-dev
is not well tested yet and there are quite some changes in it.

Have fun,

Rainer

Chris Hut schrieb:
> Hi Rainer, thanks for the reply!
> 
>> interesting use case :)
> 
> Just trying to keep things entertaining around here :)
> 
>> are you writing something back during the wait time, or are you 
>> simply
> doing processing on the backend?
> 
> Yes, the long-running process (video rendering) is also streaming the 
> video bytes back to the client using outputStream.write().  It's this 
> write (ultimately, to an org.apache.catalina.connector.OutputBuffer)
> that throws the ClientAbortException, if the client is actually gone.
> 
> So I figured out that JK is definitely holding open its connection 
> Tomcat meaning Tomcat does not know to abort.  In desperation I 
> searched for the number "30" (hoping for a constant) in the mod_jk 
> source code, and found this in jk_connect.c:
> 
> #ifndef MAX_SECS_TO_LINGER
> #define MAX_SECS_TO_LINGER 30
> #endif
> ...
> int jk_shutdown_socket(jk_sock_t s)
> {
>     ...
>     do {
>         /* Read all data from the peer until we reach "end-of-file"
>          * (FIN from peer) or we've exceeded our overall timeout. If
the
>          * backend does not send us bytes within 2 seconds
>          * (a value pulled from Apache 1.3 which seems to work well),
>          * close the connection.
>          */
>         ... /* [reads bytes] */
>     } while (difftime(time(NULL), start) < MAX_SECS_TO_LINGER); }
> 
> Sockets and low-level network programming aren't my strong suit, but 
> from searching around it sounds like this (lingering) is a common 
> practice to ensure proper TCP communication - I found a bit more info
> here: http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix
> 
> Tomcat's Http11Connector has a connectionLinger attribute (which 
> translates internally to a soLinger) which sounds like it does the 
> same thing - except that it's disabled by default.
> 
> So, does anybody know if there would be any detrimental impact to 
> re-compiling mod_jk with MAX_SECS_TO_LINGER set lower, say, 10 seconds

> or 5?  Or even lower?
> 
> Thanks again for the help!
> 
> Chris
> 
> 
> -----Original Message-----
> From: Rainer Jung [mailto:rainer.jung@kippdata.de]
> Sent: Friday, January 25, 2008 7:03 AM
> To: Tomcat Users List
> Subject: Re: Need *faster* connection abort with mod_jk
> 
> Hi Chris,
> 
> interesting use case :)
> 
> mod_jk closes the backend connection as soon as the reply_timeout 
> fires, or there is something to write back to the client and mod_jk 
> detects, that the connection to the client can not be used any longer 
> (browser stop, retry or click on another link).
> 
> If the user ends waiting for the reply and you don't try to write 
> something back, mod_jk won't detect that, because it sits there and 
> waits for something to come back from the backend. So to reliably 
> detect a browser stop, you need to actively use the connection. From 
> you comments about the mod_jk log file, it seems, that you are 
> actually doing this.
> 
> Why doesn't Tomcat immediately throw the exception: I guess (wild 
> guess), that it also only notices the closed mod_jk connection, if it 
> tries to use it. If you are actually using it continuously we would 
> have to investigate, why there is such a delay.
> 
> So first question to get closer would be: are you writing something 
> back during the wait time, or are you simply doing processing on the
backend?
> 
> In this case (because I don't understand the client abort detection of

> mod_jk then): Can you reproduce the behaviour for a single request on 
> a test system using JkLogLevel debug?
> 
> Please make sure, that the clocks on the mod_jk system and on the 
> Tomcat system are in sync.
> 
> Regards,
> 
> Rainer
> 
> Chris Hut wrote:
>> Hi all,
>>
>> We're using Apache 2.0.61 with mod_jk 1.2.25 and Tomcat 6.0.14.
>>
>> We have a simple (non-load-balanced) apache/tomcat configuration 
>> using
> 
>> a single worker to forward requests from apache to tomcat.
>> (workers.properties is below)
>>
>> Our problem is: Some client requests kick off an expensive, 
>> long-running server-side process.  Often, the client will give up 
>> (e.g. the user will navigate to a different browser page) before 
>> completion, and we want to cancel the server-side process early if
> possible.
>> We use the ClientAbortException to easily set an "interrupted" flag 
>> which our process monitors to see if it should abort.  When 
>> connecting
> 
>> straight to the servlet using Tomcat only, this is very simple as the

>> exception is thrown immediately and the process dies right away.  
>> This
> 
>> is what we hope for.
>>
>> When connecting via apache/mod_jk, though, it takes 30 seconds for 
>> the
> 
>> exception to be thrown in Tomcat.  For efficientcy we'd love the 
>> abort
> 
>> to happen immediately if possible.
>>
>> In the mod_jk.log file, we see this as soon as the client aborts
(e.g.
>> closes browser):
>>
>> [Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info] 
>> ajp_process_callback::jk_ajp_common.c (1511): Writing to client 
>> aborted or client network problems [Thu Jan 24 20:09:35.535 2008] 
>> [2011:1094711648] [info] ajp_service::jk_ajp_common.c (1996):
>> (worker1) request failed, because of client write error without 
>> recovery in send loop attempt=0
>>
>> But it takes 30 seconds to see:
>>
>> [Thu Jan 24 20:10:05.641 2008] [2011:1094711648] [info] 
>> jk_handler::mod_jk.c (2270): Aborting connection for worker=worker1
>>
>> Which corresponds exactly to the time when the ClientAbortException 
>> is
> 
>> thrown in Tomcat.
>>
>> Given the exact nature of the timing involved (30 seconds) I'm 
>> guessing/hoping this is an apache and/or JK timeout setting; however,

>> I can't find a property that would do what we require which is just 
>> to
> 
>> kill the Tomcat connection faster if the end-user client closes the 
>> connection on their side.
>>
>> Can anybody point me to a setting to tweak?  I did try using
>> recovery_options=4 (which says, "close the connection to Tomcat, if 
>> we
> 
>> detect an error when writing back the answer to the client 
>> (browser)")
> 
>> but the behavior is unchanged.  I feel like changing the worker 
>> timeouts is the wrong direction because the JK-to-Tomcat 
>> communication
> 
>> is working just fine, we just need a way to propagate JK's 
>> client-abort error to Tomcat faster!
>>
>> Thanks for your help!
>>
>> workers.properties:
>>
>> worker.list=worker1
>> worker.worker1.type=ajp13
>> worker.worker1.host=localhost
>> worker.worker1.port=8009
>> #worker.worker1.retries=4
>>
>> Chris
> 
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe,
> e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, 
> e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe,
e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Need *faster* connection abort with mod_jk

Posted by Rainer Jung <ra...@kippdata.de>.
Hi Chris,

perfect, that makes sense! Yes, we are draining the backend connection 
before closing it down, and since in your case the backend is happy to 
go along and proceed streaming it's not just a question of capturing a 
few additional bytes.

Mladen Turk added the connection draining a while ago, so we might need 
to discuss the pros and cons. The URL you gave includes a nice 
description. In our case there is no pipelining and once we finished 
sending the request (including possible request body) to the backend, 
closing without draining should be save.

I made a patch, that should disable connection draining exactly if we 
got a write error when using the client connection. The patch is 
available at

http://people.apache.org/~rjung/mod_jk-dev/patches/jk_close_immediate_on_client_wr_error.patch

(for 1.2.27-dev) and

http://people.apache.org/~rjung/mod_jk-dev/patches/jk_close_immediate_on_client_wr_error-1_2_26.patch

(for 1.2.26)

If you want to test it, I would suggest using 1.2.26, because 1.2.27-dev 
is not well tested yet and there are quite some changes in it.

Have fun,

Rainer

Chris Hut schrieb:
> Hi Rainer, thanks for the reply!
> 
>> interesting use case :)
> 
> Just trying to keep things entertaining around here :)
> 
>> are you writing something back during the wait time, or are you simply
> doing processing on the backend?
> 
> Yes, the long-running process (video rendering) is also streaming the
> video bytes back to the client using outputStream.write().  It's this
> write (ultimately, to an org.apache.catalina.connector.OutputBuffer)
> that throws the ClientAbortException, if the client is actually gone.
> 
> So I figured out that JK is definitely holding open its connection
> Tomcat meaning Tomcat does not know to abort.  In desperation I searched
> for the number "30" (hoping for a constant) in the mod_jk source code,
> and found this in jk_connect.c:
> 
> #ifndef MAX_SECS_TO_LINGER
> #define MAX_SECS_TO_LINGER 30
> #endif
> ...
> int jk_shutdown_socket(jk_sock_t s)
> {
>     ...
>     do {
>         /* Read all data from the peer until we reach "end-of-file"
>          * (FIN from peer) or we've exceeded our overall timeout. If the
>          * backend does not send us bytes within 2 seconds
>          * (a value pulled from Apache 1.3 which seems to work well),
>          * close the connection.
>          */
>         ... /* [reads bytes] */
>     } while (difftime(time(NULL), start) < MAX_SECS_TO_LINGER);
> }
> 
> Sockets and low-level network programming aren't my strong suit, but
> from searching around it sounds like this (lingering) is a common
> practice to ensure proper TCP communication - I found a bit more info
> here: http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix
> 
> Tomcat's Http11Connector has a connectionLinger attribute (which
> translates internally to a soLinger) which sounds like it does the same
> thing - except that it's disabled by default.
> 
> So, does anybody know if there would be any detrimental impact to
> re-compiling mod_jk with MAX_SECS_TO_LINGER set lower, say, 10 seconds
> or 5?  Or even lower?  
> 
> Thanks again for the help!
> 
> Chris
> 
> 
> -----Original Message-----
> From: Rainer Jung [mailto:rainer.jung@kippdata.de] 
> Sent: Friday, January 25, 2008 7:03 AM
> To: Tomcat Users List
> Subject: Re: Need *faster* connection abort with mod_jk
> 
> Hi Chris,
> 
> interesting use case :)
> 
> mod_jk closes the backend connection as soon as the reply_timeout fires,
> or there is something to write back to the client and mod_jk detects,
> that the connection to the client can not be used any longer (browser
> stop, retry or click on another link).
> 
> If the user ends waiting for the reply and you don't try to write
> something back, mod_jk won't detect that, because it sits there and
> waits for something to come back from the backend. So to reliably detect
> a browser stop, you need to actively use the connection. From you
> comments about the mod_jk log file, it seems, that you are actually
> doing this.
> 
> Why doesn't Tomcat immediately throw the exception: I guess (wild
> guess), that it also only notices the closed mod_jk connection, if it
> tries to use it. If you are actually using it continuously we would have
> to investigate, why there is such a delay.
> 
> So first question to get closer would be: are you writing something back
> during the wait time, or are you simply doing processing on the backend?
> 
> In this case (because I don't understand the client abort detection of
> mod_jk then): Can you reproduce the behaviour for a single request on a
> test system using JkLogLevel debug?
> 
> Please make sure, that the clocks on the mod_jk system and on the Tomcat
> system are in sync.
> 
> Regards,
> 
> Rainer
> 
> Chris Hut wrote:
>> Hi all,
>>
>> We're using Apache 2.0.61 with mod_jk 1.2.25 and Tomcat 6.0.14.
>>
>> We have a simple (non-load-balanced) apache/tomcat configuration using
> 
>> a single worker to forward requests from apache to tomcat.
>> (workers.properties is below)
>>
>> Our problem is: Some client requests kick off an expensive, 
>> long-running server-side process.  Often, the client will give up 
>> (e.g. the user will navigate to a different browser page) before 
>> completion, and we want to cancel the server-side process early if
> possible.
>> We use the ClientAbortException to easily set an "interrupted" flag 
>> which our process monitors to see if it should abort.  When connecting
> 
>> straight to the servlet using Tomcat only, this is very simple as the 
>> exception is thrown immediately and the process dies right away.  This
> 
>> is what we hope for.
>>
>> When connecting via apache/mod_jk, though, it takes 30 seconds for the
> 
>> exception to be thrown in Tomcat.  For efficientcy we'd love the abort
> 
>> to happen immediately if possible.
>>
>> In the mod_jk.log file, we see this as soon as the client aborts (e.g.
>> closes browser):
>>
>> [Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info] 
>> ajp_process_callback::jk_ajp_common.c (1511): Writing to client 
>> aborted or client network problems [Thu Jan 24 20:09:35.535 2008] 
>> [2011:1094711648] [info] ajp_service::jk_ajp_common.c (1996): 
>> (worker1) request failed, because of client write error without 
>> recovery in send loop attempt=0
>>
>> But it takes 30 seconds to see:
>>
>> [Thu Jan 24 20:10:05.641 2008] [2011:1094711648] [info] 
>> jk_handler::mod_jk.c (2270): Aborting connection for worker=worker1
>>
>> Which corresponds exactly to the time when the ClientAbortException is
> 
>> thrown in Tomcat.
>>
>> Given the exact nature of the timing involved (30 seconds) I'm 
>> guessing/hoping this is an apache and/or JK timeout setting; however, 
>> I can't find a property that would do what we require which is just to
> 
>> kill the Tomcat connection faster if the end-user client closes the 
>> connection on their side.
>>
>> Can anybody point me to a setting to tweak?  I did try using
>> recovery_options=4 (which says, "close the connection to Tomcat, if we
> 
>> detect an error when writing back the answer to the client (browser)")
> 
>> but the behavior is unchanged.  I feel like changing the worker 
>> timeouts is the wrong direction because the JK-to-Tomcat communication
> 
>> is working just fine, we just need a way to propagate JK's 
>> client-abort error to Tomcat faster!
>>
>> Thanks for your help!
>>
>> workers.properties:
>>
>> worker.list=worker1
>> worker.worker1.type=ajp13
>> worker.worker1.host=localhost
>> worker.worker1.port=8009
>> #worker.worker1.retries=4
>>
>> Chris
> 
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe,
> e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 
> 

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: Need *faster* connection abort with mod_jk

Posted by Chris Hut <ch...@onetruemedia.com>.
Hi Rainer, thanks for the reply!

> interesting use case :)

Just trying to keep things entertaining around here :)

> are you writing something back during the wait time, or are you simply
doing processing on the backend?

Yes, the long-running process (video rendering) is also streaming the
video bytes back to the client using outputStream.write().  It's this
write (ultimately, to an org.apache.catalina.connector.OutputBuffer)
that throws the ClientAbortException, if the client is actually gone.

So I figured out that JK is definitely holding open its connection
Tomcat meaning Tomcat does not know to abort.  In desperation I searched
for the number "30" (hoping for a constant) in the mod_jk source code,
and found this in jk_connect.c:

#ifndef MAX_SECS_TO_LINGER
#define MAX_SECS_TO_LINGER 30
#endif
...
int jk_shutdown_socket(jk_sock_t s)
{
    ...
    do {
        /* Read all data from the peer until we reach "end-of-file"
         * (FIN from peer) or we've exceeded our overall timeout. If the
         * backend does not send us bytes within 2 seconds
         * (a value pulled from Apache 1.3 which seems to work well),
         * close the connection.
         */
        ... /* [reads bytes] */
    } while (difftime(time(NULL), start) < MAX_SECS_TO_LINGER);
}

Sockets and low-level network programming aren't my strong suit, but
from searching around it sounds like this (lingering) is a common
practice to ensure proper TCP communication - I found a bit more info
here: http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix

Tomcat's Http11Connector has a connectionLinger attribute (which
translates internally to a soLinger) which sounds like it does the same
thing - except that it's disabled by default.

So, does anybody know if there would be any detrimental impact to
re-compiling mod_jk with MAX_SECS_TO_LINGER set lower, say, 10 seconds
or 5?  Or even lower?  

Thanks again for the help!

Chris


-----Original Message-----
From: Rainer Jung [mailto:rainer.jung@kippdata.de] 
Sent: Friday, January 25, 2008 7:03 AM
To: Tomcat Users List
Subject: Re: Need *faster* connection abort with mod_jk

Hi Chris,

interesting use case :)

mod_jk closes the backend connection as soon as the reply_timeout fires,
or there is something to write back to the client and mod_jk detects,
that the connection to the client can not be used any longer (browser
stop, retry or click on another link).

If the user ends waiting for the reply and you don't try to write
something back, mod_jk won't detect that, because it sits there and
waits for something to come back from the backend. So to reliably detect
a browser stop, you need to actively use the connection. From you
comments about the mod_jk log file, it seems, that you are actually
doing this.

Why doesn't Tomcat immediately throw the exception: I guess (wild
guess), that it also only notices the closed mod_jk connection, if it
tries to use it. If you are actually using it continuously we would have
to investigate, why there is such a delay.

So first question to get closer would be: are you writing something back
during the wait time, or are you simply doing processing on the backend?

In this case (because I don't understand the client abort detection of
mod_jk then): Can you reproduce the behaviour for a single request on a
test system using JkLogLevel debug?

Please make sure, that the clocks on the mod_jk system and on the Tomcat
system are in sync.

Regards,

Rainer

Chris Hut wrote:
> Hi all,
> 
> We're using Apache 2.0.61 with mod_jk 1.2.25 and Tomcat 6.0.14.
> 
> We have a simple (non-load-balanced) apache/tomcat configuration using

> a single worker to forward requests from apache to tomcat.
> (workers.properties is below)
> 
> Our problem is: Some client requests kick off an expensive, 
> long-running server-side process.  Often, the client will give up 
> (e.g. the user will navigate to a different browser page) before 
> completion, and we want to cancel the server-side process early if
possible.
> 
> We use the ClientAbortException to easily set an "interrupted" flag 
> which our process monitors to see if it should abort.  When connecting

> straight to the servlet using Tomcat only, this is very simple as the 
> exception is thrown immediately and the process dies right away.  This

> is what we hope for.
> 
> When connecting via apache/mod_jk, though, it takes 30 seconds for the

> exception to be thrown in Tomcat.  For efficientcy we'd love the abort

> to happen immediately if possible.
> 
> In the mod_jk.log file, we see this as soon as the client aborts (e.g.
> closes browser):
> 
> [Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info] 
> ajp_process_callback::jk_ajp_common.c (1511): Writing to client 
> aborted or client network problems [Thu Jan 24 20:09:35.535 2008] 
> [2011:1094711648] [info] ajp_service::jk_ajp_common.c (1996): 
> (worker1) request failed, because of client write error without 
> recovery in send loop attempt=0
> 
> But it takes 30 seconds to see:
> 
> [Thu Jan 24 20:10:05.641 2008] [2011:1094711648] [info] 
> jk_handler::mod_jk.c (2270): Aborting connection for worker=worker1
> 
> Which corresponds exactly to the time when the ClientAbortException is

> thrown in Tomcat.
> 
> Given the exact nature of the timing involved (30 seconds) I'm 
> guessing/hoping this is an apache and/or JK timeout setting; however, 
> I can't find a property that would do what we require which is just to

> kill the Tomcat connection faster if the end-user client closes the 
> connection on their side.
> 
> Can anybody point me to a setting to tweak?  I did try using
> recovery_options=4 (which says, "close the connection to Tomcat, if we

> detect an error when writing back the answer to the client (browser)")

> but the behavior is unchanged.  I feel like changing the worker 
> timeouts is the wrong direction because the JK-to-Tomcat communication

> is working just fine, we just need a way to propagate JK's 
> client-abort error to Tomcat faster!
> 
> Thanks for your help!
> 
> workers.properties:
> 
> worker.list=worker1
> worker.worker1.type=ajp13
> worker.worker1.host=localhost
> worker.worker1.port=8009
> #worker.worker1.retries=4
> 
> Chris

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe,
e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Need *faster* connection abort with mod_jk

Posted by Rainer Jung <ra...@kippdata.de>.
Hi Chris,

interesting use case :)

mod_jk closes the backend connection as soon as the reply_timeout fires, 
or there is something to write back to the client and mod_jk detects, 
that the connection to the client can not be used any longer (browser 
stop, retry or click on another link).

If the user ends waiting for the reply and you don't try to write 
something back, mod_jk won't detect that, because it sits there and 
waits for something to come back from the backend. So to reliably detect 
a browser stop, you need to actively use the connection. From you 
comments about the mod_jk log file, it seems, that you are actually 
doing this.

Why doesn't Tomcat immediately throw the exception: I guess (wild 
guess), that it also only notices the closed mod_jk connection, if it 
tries to use it. If you are actually using it continuously we would have 
to investigate, why there is such a delay.

So first question to get closer would be: are you writing something back 
during the wait time, or are you simply doing processing on the backend? 
In this case (because I don't understand the client abort detection of 
mod_jk then): Can you reproduce the behaviour for a single request on a 
test system using JkLogLevel debug?

Please make sure, that the clocks on the mod_jk system and on the Tomcat 
system are in sync.

Regards,

Rainer

Chris Hut wrote:
> Hi all,
> 
> We're using Apache 2.0.61 with mod_jk 1.2.25 and Tomcat 6.0.14.
> 
> We have a simple (non-load-balanced) apache/tomcat configuration using a
> single worker to forward requests from apache to tomcat.
> (workers.properties is below)
> 
> Our problem is: Some client requests kick off an expensive, long-running
> server-side process.  Often, the client will give up (e.g. the user will
> navigate to a different browser page) before completion, and we want to
> cancel the server-side process early if possible.
> 
> We use the ClientAbortException to easily set an "interrupted" flag
> which our process monitors to see if it should abort.  When connecting
> straight to the servlet using Tomcat only, this is very simple as the
> exception is thrown immediately and the process dies right away.  This
> is what we hope for.
> 
> When connecting via apache/mod_jk, though, it takes 30 seconds for the
> exception to be thrown in Tomcat.  For efficientcy we'd love the abort
> to happen immediately if possible.  
> 
> In the mod_jk.log file, we see this as soon as the client aborts (e.g.
> closes browser):
> 
> [Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info]
> ajp_process_callback::jk_ajp_common.c (1511): Writing to client aborted
> or client network problems
> [Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info]
> ajp_service::jk_ajp_common.c (1996): (worker1) request failed, because
> of client write error without recovery in send loop attempt=0
> 
> But it takes 30 seconds to see:
> 
> [Thu Jan 24 20:10:05.641 2008] [2011:1094711648] [info]
> jk_handler::mod_jk.c (2270): Aborting connection for worker=worker1
> 
> Which corresponds exactly to the time when the ClientAbortException is
> thrown in Tomcat.
> 
> Given the exact nature of the timing involved (30 seconds) I'm
> guessing/hoping this is an apache and/or JK timeout setting; however, I
> can't find a property that would do what we require which is just to
> kill the Tomcat connection faster if the end-user client closes the
> connection on their side.
> 
> Can anybody point me to a setting to tweak?  I did try using
> recovery_options=4 (which says, "close the connection to Tomcat, if we
> detect an error when writing back the answer to the client (browser)")
> but the behavior is unchanged.  I feel like changing the worker timeouts
> is the wrong direction because the JK-to-Tomcat communication is working
> just fine, we just need a way to propagate JK's client-abort error to
> Tomcat faster!
> 
> Thanks for your help!
> 
> workers.properties:
> 
> worker.list=worker1
> worker.worker1.type=ajp13
> worker.worker1.host=localhost
> worker.worker1.port=8009
> #worker.worker1.retries=4
> 
> Chris

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Need *faster* connection abort with mod_jk

Posted by Chris Hut <ch...@onetruemedia.com>.
Hi all,

We're using Apache 2.0.61 with mod_jk 1.2.25 and Tomcat 6.0.14.

We have a simple (non-load-balanced) apache/tomcat configuration using a
single worker to forward requests from apache to tomcat.
(workers.properties is below)

Our problem is: Some client requests kick off an expensive, long-running
server-side process.  Often, the client will give up (e.g. the user will
navigate to a different browser page) before completion, and we want to
cancel the server-side process early if possible.

We use the ClientAbortException to easily set an "interrupted" flag
which our process monitors to see if it should abort.  When connecting
straight to the servlet using Tomcat only, this is very simple as the
exception is thrown immediately and the process dies right away.  This
is what we hope for.

When connecting via apache/mod_jk, though, it takes 30 seconds for the
exception to be thrown in Tomcat.  For efficientcy we'd love the abort
to happen immediately if possible.  

In the mod_jk.log file, we see this as soon as the client aborts (e.g.
closes browser):

[Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info]
ajp_process_callback::jk_ajp_common.c (1511): Writing to client aborted
or client network problems
[Thu Jan 24 20:09:35.535 2008] [2011:1094711648] [info]
ajp_service::jk_ajp_common.c (1996): (worker1) request failed, because
of client write error without recovery in send loop attempt=0

But it takes 30 seconds to see:

[Thu Jan 24 20:10:05.641 2008] [2011:1094711648] [info]
jk_handler::mod_jk.c (2270): Aborting connection for worker=worker1

Which corresponds exactly to the time when the ClientAbortException is
thrown in Tomcat.

Given the exact nature of the timing involved (30 seconds) I'm
guessing/hoping this is an apache and/or JK timeout setting; however, I
can't find a property that would do what we require which is just to
kill the Tomcat connection faster if the end-user client closes the
connection on their side.

Can anybody point me to a setting to tweak?  I did try using
recovery_options=4 (which says, "close the connection to Tomcat, if we
detect an error when writing back the answer to the client (browser)")
but the behavior is unchanged.  I feel like changing the worker timeouts
is the wrong direction because the JK-to-Tomcat communication is working
just fine, we just need a way to propagate JK's client-abort error to
Tomcat faster!

Thanks for your help!

workers.properties:

worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
#worker.worker1.retries=4

Chris


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org