Question

In my valve I get the execution time of my http query like that :

public void invoke(Request request, Response response) 
throws IOException, ServletException {
long t1 = System.currentTimeMillis();
getNext().invoke(request, response);
long t2 = System.currentTimeMillis();
long time = t2 - t1;
...
}

I suspect that the time I get this way, not only give me the server side execution time but also the network time ? Is it possible ?

(Because depending on the client who do the request the average time measured is not the same from one ip I have 70ms average time and another ip 270ms)

I have written the exact same code in a Filter:

long before = System.currentTimeMillis();
chain.doFilter(request, response);
long after = System.currentTimeMillis();

, but in my test the execution time in the Valve and in the filter are the same...

I am more interested in getting the execution time of my servlet only. But if I could get also the time when the last byte is sent, I would be interested.

Thanks a lot to clarify me what is possible to know with valves and filters.

Was it helpful?

Solution

I suspect that the time I get this way, not only give me the server side execution time but also the network time ? Is it possible ?

That's correct. At least, a partial of the network time involving transferring the request body is included in the total time this way. The valve/filter/servlet code get invoked directly once the request headers have been fully read and parsed. The request body is not necessarily fully read at that point. The request body contains whatever the client sends over network as part of the request (e.g. submitted form data). Only when the filter/servlet starts to read and parse the full request body by e.g. getParameter(), getReader(), getInputStream(), etc, then all the bytes of the request body will actually be transferred.

You may want to rewrite your execution time measurement in such way that it only starts after the request body has been fully read. This means that you really have to measure it right inside the servlet.

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Read the request body.
    String foo = request.getParameter("foo");
    String bar = request.getParameter("bar");
    // ...

    // Now, start the stopwatch.
    long startTime = System.nanoTime();

    // Now, do the business job.
    someService.process(foo, bar, ...);
    // ...

    // Now, stop the stopwatch.
    long elapsedTime = System.nanoTime() - startTime;

    // I don't think that you want to include JSP rendering in total time, right?
    request.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
}

(note that I used System#nanoTime() as it has a much better accuracy)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top