You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2002/06/20 20:45:02 UTC

cvs commit: jakarta-tomcat-connectors/jk/native2/include jk_endpoint.h

costin      2002/06/20 11:45:02

  Modified:    jk/native2/common jk_channel_socket.c jk_handler_response.c
                        jk_workerEnv.c jk_worker_ajp13.c
               jk/native2/include jk_endpoint.h
  Log:
  2 bugs:
  - wrong POST body ( due to changes to support JNI, we reuse the request buffer
  for the response - there is no need to use 2 buffers in the roundtrip ).
  
  - if a single worker is used ( typical case ), on some cases send() doesn't detect
  that tomcat was restarted ( i.e. doesn't return an error even if the other end is
  down ). We get the error only when we do the first read.
  
  The change also deals better with recovery when we have a POST ( previously
  this didn't recover ). The 'recoverable' field is used to indicate if any
  response processing happened - if all we did was send the request head and eventually
  the initial body chunk, but the first read from tomcat fails, we'll close the
  connection and try again.
  
  It is still not perfect, I'm still working on that.
  
  No idea why write() ( or send() ) are successfull. Well, probably TCP related, I'll
   take a look with etherreal.
  
  Revision  Changes    Path
  1.34      +0 -1      jakarta-tomcat-connectors/jk/native2/common/jk_channel_socket.c
  
  Index: jk_channel_socket.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_channel_socket.c,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- jk_channel_socket.c	19 Jun 2002 18:27:25 -0000	1.33
  +++ jk_channel_socket.c	20 Jun 2002 18:45:01 -0000	1.34
  @@ -358,7 +358,6 @@
       
       while(sent < len) {
           int this_time = write(sd, (char *)b + sent , len - sent);
  -        fprintf(stderr, "WRITE: %d %d %d\n", this_time, len, errno);
   	if(0 == this_time) {
   	    return -2;
   	}
  
  
  
  1.22      +3 -0      jakarta-tomcat-connectors/jk/native2/common/jk_handler_response.c
  
  Index: jk_handler_response.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_handler_response.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- jk_handler_response.c	10 Jun 2002 21:55:06 -0000	1.21
  +++ jk_handler_response.c	20 Jun 2002 18:45:01 -0000	1.22
  @@ -239,6 +239,9 @@
           len = 0;
       }
   
  +/*     env->l->jkLog(env, env->l, JK_LOG_INFO, */
  +/*                   "handler_request.getChunk() - read len=%d\n",len); */
  +
       len=msg->appendFromServer( env, msg, r, ae, len );
       /* the right place to add file storage for upload */
       if (len >= 0) {
  
  
  
  1.55      +13 -8     jakarta-tomcat-connectors/jk/native2/common/jk_workerEnv.c
  
  Index: jk_workerEnv.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_workerEnv.c,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -r1.54 -r1.55
  --- jk_workerEnv.c	12 Jun 2002 12:40:17 -0000	1.54
  +++ jk_workerEnv.c	20 Jun 2002 18:45:01 -0000	1.55
  @@ -426,9 +426,10 @@
           return JK_ERR;
       }
   
  -/*     env->l->jkLog(env, env->l, JK_LOG_INFO, */
  -/*                   "workerEnv.dispatch() Calling %d %s\n", handler->messageId, */
  -/*                   handler->name); */
  +    if( wEnv->mbean->debug > 0 ) 
  +        env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                      "workerEnv.dispatch() Calling %d %s\n", handler->messageId,
  +                      handler->name);
       
       /* Call the message handler */
       rc=handler->callback( env, target, e, msg );
  @@ -480,12 +481,16 @@
           if( rc!=JK_OK ) {
               env->l->jkLog(env, env->l, JK_LOG_ERROR,
                             "workerEnv.processCallbacks() Error reading reply\n");
  -            /* Probably protocol error, we can't recover
  +            /* It may be the first receive, let the caller decide if it's ok to retry
                */
  -            ep->recoverable=JK_FALSE;
  +            /* ep->recoverable=JK_FALSE; */
               return rc;
           }
   
  +        /** After I received the first message ( head most likely ), it
  +            is impossible to recover */
  +        ep->recoverable=JK_FALSE;
  +        
           if( ep->worker->mbean->debug > 10 )
               ep->request->dump( env, msg, "Received" );
   
  @@ -517,9 +522,9 @@
                */
               req->is_recoverable_error = JK_FALSE;
               if( ep->worker->mbean->debug > 10 )
  -                ep->request->dump( env, ep->post, "Apache->tomcat" );
  +                msg->dump( env, msg, "Apache->tomcat" );
   
  -            rc = ep->worker->channel->send(env, ep->worker->channel, ep, ep->post );
  +            rc = ep->worker->channel->send(env, ep->worker->channel, ep, msg );
               if (rc < 0) {
                   env->l->jkLog(env, env->l, JK_LOG_ERROR,
                                 "ajp14.processCallbacks() error sending response data\n");
  
  
  
  1.33      +71 -85    jakarta-tomcat-connectors/jk/native2/common/jk_worker_ajp13.c
  
  Index: jk_worker_ajp13.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_worker_ajp13.c,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- jk_worker_ajp13.c	12 Jun 2002 12:40:17 -0000	1.32
  +++ jk_worker_ajp13.c	20 Jun 2002 18:45:01 -0000	1.33
  @@ -291,16 +291,17 @@
   */
   #define JK_RETRIES 2
   
  -/** First message in a stream-based connection. If the first send
  -    fails, try to reconnect.
  -*/
  +
   static int JK_METHOD
  -jk2_worker_ajp13_sendAndReconnect(jk_env_t *env, jk_worker_t *worker,
  -                                  jk_ws_service_t *s,
  -                                  jk_endpoint_t   *e )
  +jk2_worker_ajp13_forwardStream(jk_env_t *env, jk_worker_t *worker,
  +                              jk_ws_service_t *s,
  +                              jk_endpoint_t   *e )
   {
  -    int attempt;
       int err=JK_OK;
  +    int attempt;
  +
  +    e->recoverable = JK_TRUE;
  +    s->is_recoverable_error = JK_TRUE;
       
       /*
        * Try to send the request on a valid endpoint. If one endpoint
  @@ -318,7 +319,6 @@
                   env->l->jkLog(env, env->l, JK_LOG_ERROR,
                                 "ajp13.service() failed to connect endpoint errno=%d %s\n",
                                 errno, strerror( errno ));
  -
                   e->worker->in_error_state=JK_TRUE;
                   return err;
               }
  @@ -330,91 +330,77 @@
           if( e->worker->mbean->debug > 10 )
               e->request->dump( env, e->request, "Sent" );
           
  -        if (err==JK_OK ) {
  -            /* We sent the request, have valid endpoint */
  -            break;
  -        }
  -
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                      "ajp13.service() error sending, reconnect %s %d %d %s\n",
  -                      e->worker->channelName, err, errno, strerror(errno));
  -
  -        channel->close( env, channel, e );
  -        e->sd=-1;
  -    }
  -    return JK_OK;
  -}
  -
  -
  -static int JK_METHOD
  -jk2_worker_ajp13_forwardStream(jk_env_t *env, jk_worker_t *worker,
  -                              jk_ws_service_t *s,
  -                              jk_endpoint_t   *e )
  -{
  -    int err;
  -
  -    e->recoverable = JK_TRUE;
  -    s->is_recoverable_error = JK_TRUE;
  +        if (err!=JK_OK ) {
  +            /* Can't send - bad endpoint, try again */
   
  -    err=jk2_worker_ajp13_sendAndReconnect( env, worker, s, e );
  -    if( err!=JK_OK )
  -        return err;
  -    
  -    /* We should have a channel now, send the post data */
  -
  -    /* Prepare to send some post data ( ajp13 proto ). We do that after the
  -     request was sent ( we're receiving data from client, can be slow, no
  -     need to delay - we can do that in paralel. ( not very sure this is
  -     very usefull, and it brakes the protocol ) ! */
  -    if (s->is_chunked || s->left_bytes_to_send > 0) {
  -        /* We never sent any POST data and we check it we have to send at
  -	 * least of block of data (max 8k). These data will be kept in reply
  -	 * for resend if the remote Tomcat is down, a fact we will learn only
  -	 * doing a read (not yet) 
  -	 */
  -        err=jk2_serialize_postHead( env, e->post, s, e );
  +            env->l->jkLog(env, env->l, JK_LOG_ERROR,
  +                          "ajp13.service() error sending, reconnect %s %d %d %s\n",
  +                          e->worker->channelName, err, errno, strerror(errno));
  +            jk2_close_endpoint(env, e );
  +            continue;
  +        }
   
  -        if( e->worker->mbean->debug > 10 )
  -            e->request->dump( env, e->request, "Post head" );
  +        /* We should have a channel now, send the post data */
  +        
  +        /* Prepare to send some post data ( ajp13 proto ). We do that after the
  +           request was sent ( we're receiving data from client, can be slow, no
  +           need to delay - we can do that in paralel. ( not very sure this is
  +           very usefull, and it brakes the protocol ) ! */
  +        if (s->is_chunked || s->left_bytes_to_send > 0) {
  +            /* We never sent any POST data and we check it we have to send at
  +             * least of block of data (max 8k). These data will be kept in reply
  +             * for resend if the remote Tomcat is down, a fact we will learn only
  +             * doing a read (not yet) 
  +             */
  +            if( attempt==0 )
  +                err=jk2_serialize_postHead( env, e->post, s, e );
  +            
  +            if( e->worker->mbean->debug > 10 )
  +                e->request->dump( env, e->request, "Post head" );
  +            
  +            if (err != JK_OK ) {
  +                /* the browser stop sending data, no need to recover */
  +                /* e->recoverable = JK_FALSE; */
  +                s->is_recoverable_error = JK_FALSE;
  +                env->l->jkLog(env, env->l, JK_LOG_ERROR,
  +                              "ajp13.service() Error receiving initial post \n");
  +                return JK_ERR;
  +            }
  +            err= e->worker->channel->send( env, e->worker->channel, e,
  +                                           e->post );
  +            if( err != JK_OK ) {
  +                /* e->recoverable = JK_FALSE; */
  +                s->is_recoverable_error = JK_FALSE;
  +                env->l->jkLog(env, env->l, JK_LOG_ERROR,
  +                              "ajp13.service() Error receiving initial post \n");
  +                return JK_ERR;
  +            }
  +        }
   
  -        if (err != JK_OK ) {
  -            /* the browser stop sending data, no need to recover */
  -            e->recoverable = JK_FALSE;
  +        
  +        err = e->worker->workerEnv->processCallbacks(env, e->worker->workerEnv,
  +                                                     e, s);
  +        
  +        /* if we can't get reply, check if no recover flag was set 
  +         * if is_recoverable_error is cleared, we have started received 
  +         * upload data and we must consider that operation is no more recoverable
  +         */
  +        if (err!=JK_OK && ! e->recoverable ) {
               s->is_recoverable_error = JK_FALSE;
               env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                          "ajp13.service() Error receiving initial post \n");
  +                          "ajp13.service() ajpGetReply unrecoverable error %d\n",
  +                          err);
               return JK_ERR;
           }
  -        err= e->worker->channel->send( env, e->worker->channel, e,
  -                                       e->post );
  +        
           if( err != JK_OK ) {
  -            e->recoverable = JK_FALSE;
  -            s->is_recoverable_error = JK_FALSE;
               env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                          "ajp13.service() Error receiving initial post \n");
  -            return JK_ERR;
  -        }
  -    }
  -
  -    err = e->worker->workerEnv->processCallbacks(env, e->worker->workerEnv,
  -                                                 e, s);
  -    
  -    /* if we can't get reply, check if no recover flag was set 
  -     * if is_recoverable_error is cleared, we have started received 
  -     * upload data and we must consider that operation is no more recoverable
  -     */
  -    if (! e->recoverable) {
  -        s->is_recoverable_error = JK_FALSE;
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                      "ajp13.service() ajpGetReply unrecoverable error %d\n",
  -                      err);
  -        return JK_ERR;
  -    }
  -
  -    if( err != JK_OK ) {
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                      "ajp13.service() ajpGetReply recoverable error %d\n",
  -                      err);
  +                          "ajp13.service() ajpGetReply recoverable error %d\n",
  +                          err);
  +            jk2_close_endpoint(env, e ); 
  +       }
  +        if( err==JK_OK )
  +            return err;
       }
       return err;
   }
  @@ -534,7 +520,7 @@
           return JK_ERR;
       }
       
  -    if( ! e->recoverable ||  w->in_error_state ) {
  +    if( w->in_error_state ) {
           jk2_close_endpoint(env, e);
           /*     if( w->mbean->debug > 0 )  */
           env->l->jkLog(env, env->l, JK_LOG_INFO,
  
  
  
  1.16      +10 -7     jakarta-tomcat-connectors/jk/native2/include/jk_endpoint.h
  
  Index: jk_endpoint.h
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/include/jk_endpoint.h,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- jk_endpoint.h	16 May 2002 20:49:53 -0000	1.15
  +++ jk_endpoint.h	20 Jun 2002 18:45:02 -0000	1.16
  @@ -169,12 +169,15 @@
       char *readBuf;
       int bufPos;
       
  -    /* JK_TRUE if the endpoint can be reused ( after an error ).
  -     * JK_FALSE if we must close the connection - for example we have
  -     * packet/marshalling error.
  -     * This is different from req->is_recoverable_error, which just
  -     * specifies that the request can be sent to another tomcat.
  -     * Set by workerEnv if a handler returns JK_HANDLER_ERROR.
  +    /* JK_TRUE if we can recover by sending the request to a different
  +     * worker. This happens if only the request header and initial body
  +     * chunk has been set. 
  +     * 
  +     * JK_FALSE if we already received data from a tomcat instance. In
  +     * this case there is no point in retrying the current request and
  +     * we must fail.
  +     *
  +     * The connection with the current tomcat is closed in any case.
        */
       int     recoverable;        
   
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>