简体   繁体   中英

How can we stop backend process?

In my spring boot application, I have below REST service

@GetMapping("/testThread")
public Map<String, Object> testThread(HttpServletRequest request){

    for (int i=0;i<100000;i++){
        System.out.println(i);
    }
    return null;
}

In this web service, I am calling from POSTMAN tool and in this webservice loop is running 100 000 times.

My requirement is after calling web service from postman then i am able to cancel that request by using Cancel Request button, then in back end loop also should stop.

As of now loop is completing its execution.

Do we have any option to do so ?

You have two prototype options, the first is the requesting thread somehow cancels the request. As you are doing the work before you return the response you could in-theory send some data down the pipe with every iteration, for example, a space character and then flush the output writer. If the caller has closed the pipe you will get an IOException and that will terminate the loop. It's very hacky though.

The alternative is to return some sort of identifier for the worker thread so that a cancel command can be sent which identifies which thread is should be cancelled. To do this you are going to need to push your worker thread into a new thread and return a response that contains the worker identifier immediately. That means the initial client call gets a response straight away even though the worker thread is still working.

Note that the example below only works in a single server or sticky load-balanced environment. You could, of course, extend the state map to a database table for more complex architectures.

You may also want to add further endpoints to get the current state or results.

private enum State {
   Running,
   Cancel
}

private final Map<String, State> state = Collections.synchronizedMap(new HashMap<>());
private final ExecutorService executor = Executors.newCachedThreadPool();

@GetMapping("/cancelThread/{id}")
public Map<String, Object> testThread(@PathVariable String id) {
    state.computeIfPresent(id, (k, v) -> State.Cancel);
}

@GetMapping("/testThread")
public Map<String, Object> testThread(HttpServletRequest request) {
    String id = java.util.UUID.randomUUID().toString()
    state.put(id, State.Running);

    executor.submit(() -> doWork(id));

    Map<String, Object> response = new HashMap<>();
    response.put("transactionId", id);
    return response;
}

private void doWork(String id) {
    executor.submit(() -); 

    try {
        for (int i = 0; i < 100000; i++) {
          if (state.get(id) == State.Cancel) {
              break;
          }

          System.out.println(i);
        }
    } finally {
        state.remove(id);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM