Jersey Rest API возвращается немедленно, и длинная задача продолжается - PullRequest
0 голосов
/ 08 октября 2018

У меня есть требование в моем проекте, где пользователь вызывает REST API - POST Operation для выполнения задачи длительного ожидания, теперь вместо того, чтобы заставлять пользователя ждать, мы хотим немедленно уведомить пользователя, говоря «Задача принята», и вфоновый запуск другого потока для выполнения длинной задачи.

Я попробовал приведенный ниже код, но в тот момент, когда API возвращает другие потоки, они не регистрируют никаких сообщений или не выполняют никаких задач.Чего мне не хватает здесь.

@POST
@Path("/longtask")
@Consumes(MediaType.APPLICATION_JSON)
public Response longTask() {
    LOGGER.info("longTask started by Thread: "+Thread.currentThread().getName());
    executor.submit(
            new Runnable() {
                @Override
                public void run() {
                    new AsyncService().longTask();
                }
            });       
    LOGGER.info("longTask completed by Thread: "+Thread.currentThread().getName());
    return Response.ok(new MyResponse<>("Task Accepted")).build();
}

AsyncService

public class AsyncService {

    /**
     *
     */
    public void longTask(){
        LOGGER.info("AsyncService - longTask() Started: "+Thread.currentThread().getName());
        try{
            //Tried thenAcceptAsync as well
            CompletableFuture.supplyAsync(new MyAsyncSupplier()).thenAccept(new MyAsyncConsumer());
        }finally{
            LOGGER.info("AsyncService - longTask() Completed: "+Thread.currentThread().getName());
        }

    }   

}

MyAsyncSupplier () и MyAsyncConsumer () - это некоторые задачи, которые вызывают БД и выполняют задачу длительного ожидания.Регистраторы под MyAsyncSupplier () и MyAsyncConsumer () не печатаются.Я попробовал то же самое только с примером проекта Java и метода main (), и то же самое произошло.В тот момент, когда основной завершает System.out's не распечатываются.

[744832b5-deed-4043-11-111] [myproject] 2018-10-08 18:19:16,836 [http-nio-8080-exec-31] INFO  mypackage.MyResource - longTask started by Thread: http-nio-8080-exec-31
[744832b5-deed-4043-11-111] [myproject] 2018-10-08 18:19:16,836 [http-nio-8080-exec-31] INFO  mypackage.MyResource - longTask completed by Thread: http-nio-8080-exec-31
[] [] 2018-10-08 18:19:16,837 [pool-64-thread-1] INFO  mypackage.AsyncService - AsyncService - longTask() Started: pool-64-thread-1
[744832b5-deed-4043-11-11] [myproject] 2018-10-08 18:19:16,844 [http-nio-8080-exec-31] DEBUG mypackage.InitializationResponseFilter - Media Type set to : application/json 

Как я могу продолжить выполнение этой задачи?

CompletableFuture.supplyAsync(new MyAsyncSupplier()).thenAccept(new MyAsyncConsumer());

Обновление 1:

Приведенный выше код не работал из-за некоторых классов MyAsyncSupplier и MyAsyncConsumerПроблемы с назначением объектов.Я продолжил отладку кода, и после исправления он работал.

Обновление 2:

На самом деле не было необходимости отправлять запрос исполнителю.

@POST
@Path("/longtask")
@Consumes(MediaType.APPLICATION_JSON)
public Response longTask() {
    LOGGER.info("longTask started by Thread: "+Thread.currentThread().getName());
    new AsyncService().longTask();
    LOGGER.info("longTask completed by Thread: "+Thread.currentThread().getName());
    return Response.ok(new MyResponse<>("Task Accepted")).build();
}

1 Ответ

0 голосов
/ 08 октября 2018

Я думаю, что код, который вы разместили, в порядке и работает, как и ожидалось.Возможно, ваша реализация MyAsyncSupplier и MyAsyncSupplier неверна.Вот моя реализация дать ему шанс.

public class FunFun {
    ExecutorService executor = Executors.newFixedThreadPool(2);

    public static void main(String[] args) {
        FunFun f = new FunFun();
        f.longTask();
        f.shutdown();
//        Scanner scanner = new Scanner(System.in); changed to use shutdown.
//        scanner.nextLine();
//        System.exit(0);
    }

    public void shutdown() {
        executor.shutdown();
    }

    public String longTask() {
        System.out.println("longTask started by Thread: "+Thread.currentThread().getName());
        executor.submit(
                new Runnable() {
                    @Override
                    public void run() {
                        new AsyncService().longTask();
                    }
                });
        System.out.println("longTask completed by Thread: "+Thread.currentThread().getName());
        return "Task Accepted";
    }

    public class AsyncService {
        public void longTask(){
            System.out.println("AsyncService - longTask() Started: "+Thread.currentThread().getName());
            try{
                //Tried thenAcceptAsync as well
                CompletableFuture.supplyAsync(new MyAsyncSupplier()).   thenAcceptAsync(new MyAsyncConsumer());
            }finally{
                System.out.println("AsyncService - longTask() Completed: "+Thread.currentThread().getName());
            }
        }
    }

    public class MyAsyncSupplier implements Supplier<String>{

        @Override
        public String get() {
            System.out.println("Supplying Food");
            return "Food";
        }

    }

    public class MyAsyncConsumer implements Consumer<String>{

        @Override
        public void accept(String t) {
            System.out.println("Nom Nom " + t);
        }
    }
}

Вывод:

longTask started by Thread: main
longTask completed by Thread: main
AsyncService - longTask() Started: pool-1-thread-1
Supplying Food
Nom Nom Food
AsyncService - longTask() Completed: pool-1-thread-1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...