1

I have a task that I want to wrap in a servlet to provide the ability to run the task remotely, by http request.

I know I can achieve this with REST API, but currently I assume (and please correct me if I'm wrong) that a simple servlet will do.

One of the things I want to achieve is that if a request to the servlet is made while another request is still processed, I'll get an appropriate response - "Task is already running".

I've built a simple servlet, using servlet-3.0, that calls the jar I want to run, but when I make 2 requests, the second one is not processed until the first one is finished.

EDIT:

My servlet is a simple http serlvet. service method overriden. I have a system.out.println("a") in the start. when I call the servlet in debug mode and then (while stopped at breakpoint) call it again, the message is printed only one time and printed the second time when I release the breakpoint and the first run finishes.

user1997656
  • 532
  • 1
  • 6
  • 20
  • You wrote that you don't want to use REST API. Can you tell us why? It's really easy to create REST using JAX-RS/Jersey. – pepuch Mar 20 '13 at 07:09
  • 2
    Servlet always responds multiple request. – AmitG Mar 20 '13 at 07:09
  • 2
    You want to make your servlet singlethreaded - why? The servlet container will by default handle more requests for you. – Darwind Mar 20 '13 at 07:09
  • 1
    Can you post your servlet code please? – Sudhanshu Umalkar Mar 20 '13 at 07:10
  • Related question: [Difference between each instance of servlet and each thread of servlet in servlets?](http://stackoverflow.com/q/2183974/1065197) – Luiggi Mendoza Mar 20 '13 at 07:33
  • A possible solution would be having another component in your server that handles these jobs in parallel and you can ask about the state of current work i.e. a Resource Adapter Module (rar) that process the jobs and you communicate both the web and the rar modules using JMS. – Luiggi Mendoza Mar 20 '13 at 07:45

2 Answers2

0

First of all, this does not seems like REST at all. If you really just want to spawn a (single) background task, make sure you do it in a separate worker thread, not the request thread.

NilsH
  • 13,705
  • 4
  • 41
  • 59
  • In a servlet, I think it's safe to have blocking doGet() etc. handlers but scalability could be an issue. – seand Mar 20 '13 at 07:24
0

Maybe you need a lock:

public class Task extends HttpServlet {
    // for singleton
    //private volatile boolean running = false;

    // or try this:

    public static boolean running = false;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
    {
        if(running){
             PrintWriter out = response.getWriter();
             out.println("running");
             return;
        }
        synchronized(Task.class){
            if(!running){
                running = true;
                // run the task
                running = false;
            }
        }
    }
}
lichengwu
  • 4,277
  • 6
  • 29
  • 42
  • 1
    If he's using multiple http servers you'll need to lock on something external such as a database. – seand Mar 20 '13 at 07:26
  • 1
    Synchronized(this) won't work since the servlet container normally instantiates one servlet per request. You need a static run variable and a static lock. Syncin on the class would do. – Alexander Torstling Mar 20 '13 at 07:33
  • It's not always correct that servlet instance is created for every servlet. – Ramesh PVK Mar 20 '13 at 08:35