sreisman
sreisman

Reputation: 668

Java ExecutorService REST call error

I am trying to use Java's ExecutorService to send out concurrent REST requests which make various logs of system information (coming from a controller), however am running into a bug. About half of my requests successfully make it to the target, but the other half appear as if they are sent, but are not found on the server they were sent to. I think I may have a flaw in the logic of setting up my ExecutorService. The function log() shown below can be called from a REST call to the controller, and is supposed to create a new thread which sends out a separate HTTP request, and continue with the main thread so as not to wait for the network I/O. After much searching, I believe I have the ExecutorService shutdown properly an wait for the thread to complete. Can anybody see some type of error in the logic of my thread creation, as multiple requests from the controller can continue to come in?

//Controller
//code
 @RequestMapping(value="/log", method= RequestMethod.GET)
public String log()
{
    genomicsLogger.log(Severity.err, Category.LOG, "This is a log from the reporting manager!");
    return "Hopefully logged";
}


//ClassB
public String log(String trns , String user, Severity severity, Category category, String msg) {
                trnsField = trns;
                userField = user;
                ...
                ...
                ...
                ExecutorService executor = Executors.newFixedThreadPool(1);
                Runnable task = () -> {



                        try {
                            System.out.println("Started thread: " + Thread.currentThread().getName());
                            restService.consumeRest(true, instance.getUri().toString(), LOG_URI, list, log, HttpMethod.POST, new HttpHeaders(), String.class);
                            System.out.println("SENT REST REQUEST");
                        } catch (URISyntaxException e) {
                            e.printStackTrace();
                        } catch (KeyStoreException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (CertificateException e) {
                            e.printStackTrace();
                        } catch (NoSuchAlgorithmException e) {
                            e.printStackTrace();
                        } catch (UnrecoverableKeyException e) {
                            e.printStackTrace();
                        } catch (KeyManagementException e) {
                            e.printStackTrace();
                        }

                    }
                };
                    executor.submit(task);
                try {
                    System.out.println("attempt to shutdown executor");
                    executor.shutdown();
                    executor.awaitTermination(5, TimeUnit.SECONDS);
                }
                catch (InterruptedException e) {
                    System.err.println("tasks interrupted");
                }
                finally {
                    if (!executor.isTerminated()) {
                        System.err.println("cancel non-finished tasks");
                    }
                    executor.shutdownNow();
                    System.out.println("shutdown finished");
                }

                return "";
            }

Upvotes: 0

Views: 775

Answers (1)

Krzysztof Krasoń
Krzysztof Krasoń

Reputation: 27476

You are creating executor service with each log and killing it.

This is not the way to use it, it is meant to be reused, make it e.g. a field in this class and set some number of threads that you are willing to use for it (probably higher than 1). And don't do shutdown on it until you are really sure it won't be used (e.g. during application shutdown).

Upvotes: 1

Related Questions