Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-users] Concurrent Requests in embedded jetty, some responses return empty body

Thank you very much. That indeed seem to solve the issue.

Am 25.03.14 14:24, schrieb Joakim Erdfelt:
A few things to address ...

Don't put HttpServletResponse and PrintWriter as field members.
Keep in mind that you have 1 instance and multiple requests.

Don't call baseRequest.setHandled(true) till you are done handling the request.
Don't forget to close your writer.

Using the try-with-resources pattern that might make this easier for you (as PrintWriter is an AutoCloseable resource)

try(PrintWriter writer = response.getWriter())
{
   // your logic on what content to respond with.
   writer.println("Hello");
} finally {
   baseRequest.setHandled(true)
}

Under Jetty, you can have multiple handlers work with the same response.getWriter(), merely ending the handler, or setting the baseRequest.setHandled(true) is not sufficient to let jetty know that the response is done.
If you don't want to close the PrintWriter, at least flush it. (but know that an unclosed Writer will result in Jetty issuing the response content as chunked)
(Note: the Handler behavior in this regard is different than the Servlet behavior)

--
Joakim Erdfelt <joakim@xxxxxxxxxxx>
Expert advice, services and support from from the Jetty & CometD experts


On Tue, Mar 25, 2014 at 1:17 AM, Enrico Kern <kern@xxxxxxxxxxx> wrote:
Hello,

i try to create a simple java application with jetty 9 embedded and one handler. The application receives status polls every few seconds, but some requests can take up to 20 seconds on the server to process.

I figured out that sometimes the longer taking requests return a empty body in the response. This only happens if other requests are served by the jetty aswell. So i created a little dummy application and have the same behavior here. Im pretty new to jetty and just cant figure out what i do wrong.  Maybe someone can give me a hint.

The problem is easy to replicate using then curl in one window:

#!/bin/bash
while(true); do
        curl localhost:44999
        sleep 1
done

which is the short request every second. And the long one which will wait 2 seconds in the handler (in the real application some command is executed here and the handler waits for it to return)

#!/bin/bash
while(true); do
        curl -i 127.0.0.1:44999/MEEEH/whyunotwork
        sleep 1
done

the second curl loop will only return content if the first curl run is stopped. Headers are ok. Just the writer.println content is missing.  Im pretty sure i do something wrong here.

Thats how i start the server:


         // Jetty
          Server server = new Server(44000);
          server.setHandler(new CheckJettyHandler());
          System.out.println("Starting Jetty on Port 44000");
          server.start();
          server.join();

and the handler:

package jettytest;


import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.logging.Level;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;

/**
 *
 * @author teeesting
 */
public class CheckJettyHandler extends AbstractHandler {
    Logger logger = Logger.getRootLogger();
    private HttpServletResponse response;
    private PrintWriter writer;

    public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse p_response)
        throws IOException, ServletException
    {

        if(!target.equals("/favicon.ico"))
        {
            logger.info("Request from ["+baseRequest.getRemoteAddr()+"] : " + target);
        }
        response = p_response;
        response.setContentType("text/html;charset=utf-8");
        response.setHeader("Server", "Blabla Test ");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setCharacterEncoding("utf-8");
        writer = response.getWriter();

        baseRequest.setHandled(true);

        List l_lTargets = new ArrayList();
        StringTokenizer st = new StringTokenizer(target,"/");
        while (st.hasMoreTokens()) {
            String l_strToken = st.nextToken();
            l_lTargets.add(l_strToken);
            //response.getWriter().println(st.nextToken());
        }

        // multi request?
        if(l_lTargets.size() > 1)
        {
           try {
                Thread.sleep(2000);
            } catch (InterruptedException ex) {
java.util.logging.Logger.getLogger(CheckJettyHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
           writer.println("Hello");
        }
        else
        {
           // single requests
           response.setStatus(HttpServletResponse.SC_FORBIDDEN);
           writer.println("invalid authorisation key");
        }

    }

--
[Clavain Technologies GbR]

Gesellschafter: Enrico Kern, Robin Elster
kern@xxxxxxxxxxx
www.clavain.com

Heerstraße 366
13593 Berlin
GERMANY

PHONE: +49 30 89398336

_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users



_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users


-- 
[Clavain Technologies GbR] 

Gesellschafter: Enrico Kern, Robin Elster 
kern@xxxxxxxxxxx
www.clavain.com

Heerstraße 366 
13593 Berlin 
GERMANY 

PHONE: +49 30 89398336 

Back to the top