
Mikhail
12.09.2017
11:11:20
Смотрю в давно напиленный spring batch job
там стоит commitInterval = 500
соответственно, всё окей, у нас больше 200-то и не бывает
меняю на 50

Google

Mikhail
12.09.2017
11:11:56
запускаю
первые 50 коммитятся в базу, после чего подключение к БД закрывается ко всем херам
Это что еще за штучки?

Sergey
12.09.2017
11:27:39
так это и есть сколько записей в батче

Mikhail
12.09.2017
12:39:20
ну нахер, тут ваще спринг батч не нужен
надо переписать

Gregory
12.09.2017
12:55:08
Знатоки спринга подскажут?
Можно ли сделать асинхронный Interceptor (или на Filter) в спринге следующим образом:
1. В условном preHandle запустить асинхронную таску.
2. После завершения таски выполнится основной метод контроллера.
3. При этом поток, в котором запустилась обработка (preHandle) не блокируется, т.е. вообще всё асинхронно.

Sergey
12.09.2017
12:57:37
а зачем? у тебя в любом случае 1 воркер на 1 запрос
если какой-нибудь undertow

Aleksander
12.09.2017
12:57:59
Не понимаю, что и зачем хочешь сделать.
Если имеется в виду, что ты запустил таску и одновременно выполняешь контроллер

Google

Aleksander
12.09.2017
13:01:14
То я бы обернул в фильтре response в onCommitedResponseWrapper, запустил таску и во враппере переопределил onResponseCommited с ожиданием выполнения таски
Если я правильно понял то, что ты хочешь, а не то, что ты написал - если я не прав напиши детали
Но, это можно сделать и в контроллере. А ещё есть замечательный класс DefferedResult(или CompletableFuture, whatever) который отпускает треды томката

Igor
12.09.2017
13:09:05
Кто-нибудь перешел на JUnit 5?
Есть там какие-нибудь интересные фичи (типа property tests или тестирование стат. методов)?

Sergey
12.09.2017
13:11:08
Junit же еще не релизнулся?

Aleksander
12.09.2017
13:11:44
Мы пробовали в нашем опенсорном шаблонизаторе. Когда я начал пилить интеграцию со спрингом - отхватил много боли
В тестах
Но это было год назад

Gregory
12.09.2017
13:15:28

Aleksander
12.09.2017
13:15:59

Vladislav
12.09.2017
13:16:08
Как в Java получить класс параметризированного дженерика?
Типа:
Class<List<Integer>> c = List<Integer>.class;
но так не компилится

Gregory
12.09.2017
13:16:48
В Interceptor общая логика выполняется (связанная, например, с авторизацией).

Dmitry
12.09.2017
13:17:17
в общем случае — никак
type erasure и все такое

Vladislav
12.09.2017
13:17:48
ну чтобы указать правильный класс для десериализации, например

Aleksander
12.09.2017
13:18:15
точнее код
набросаю

Google

Dmitry
12.09.2017
13:18:27
если используешь Jackson, то смотри в сторону TypeReference

Gregory
12.09.2017
13:18:29
Ок, спасибо.

Vladislav
12.09.2017
13:18:35
Map<String, Object> m = new ObjectMapper().convertType(obj, Map<String, Object>.class);

Митко Соловец?
12.09.2017
13:19:16

Dmitry
12.09.2017
13:19:55
Map<String, Object> m = new ObjectMapper().convertType(obj, new TypeReference<Map<String, Object>>() {});

Митко Соловец?
12.09.2017
13:20:00
http://www.baeldung.com/jackson-collection-array

Dmitry
12.09.2017
13:20:01
чет тип того

Митко Соловец?
12.09.2017
13:20:11
в этой статье все варианты рассмотрены

Vladislav
12.09.2017
13:21:10
спасибо, погляжу

Aleksander
12.09.2017
13:26:02
Ок, спасибо.
public class WhateverFilter extends OncePerRequestFilter {
//На примере фильтра
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
//Долгая - долгая таска.
CompletableFuture<Integer> asyncTask = CompletableFuture.supplyAsync(() -> {
int counter = 0;
//неважно что тут.
for (int i = 0; i < 1_000_000; i++, counter++) {
}
return counter;
});
//Оборачиваем response во враппер, onResponseCommitted вызовется ровно до того, как отдастся ответ
//пользователю. Т.е. самая последняя точка, перед тем как юзер что-то получит
filterChain.doFilter(request, new OnCommittedResponseWrapper(response) {
@Override
protected void onResponseCommitted() {
//Дожидаемся выполнения задачи, чтобы она точно выполнилась, до того, как юзер получит
//результат
asyncTask.join();
}
});
}
}


Gregory
12.09.2017
13:41:28
public class WhateverFilter extends OncePerRequestFilter {
//На примере фильтра
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
//Долгая - долгая таска.
CompletableFuture<Integer> asyncTask = CompletableFuture.supplyAsync(() -> {
int counter = 0;
//неважно что тут.
for (int i = 0; i < 1_000_000; i++, counter++) {
}
return counter;
});
//Оборачиваем response во враппер, onResponseCommitted вызовется ровно до того, как отдастся ответ
//пользователю. Т.е. самая последняя точка, перед тем как юзер что-то получит
filterChain.doFilter(request, new OnCommittedResponseWrapper(response) {
@Override
protected void onResponseCommitted() {
//Дожидаемся выполнения задачи, чтобы она точно выполнилась, до того, как юзер получит
//результат
asyncTask.join();
}
});
}
}
В данном примере выполнение метода контроллера и таска из Filter не упорядочены. Хочется получить что-то наподобие того, как реализуется цеочка CompletionStage при выполнении CompletableFuture.


Aleksander
12.09.2017
13:42:13

Aleksander
12.09.2017
13:43:14
Любая цепочка в completableFuture это синхрон, просто в разных тредах
Вот тебе задачка, как думаешь в каких тредах выполнится supplyAsync и thenApply?
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> null).thenApply(result -> result).join();
}

Ivan
12.09.2017
13:47:33

Aleksander
12.09.2017
13:47:45
Три варианта ответа: в треде common pool, в треде мейн или нерегламентированно?

Gregory
12.09.2017
13:49:35
Цель в том, чтобы избежать множества потоков в состоянии wait, чтобы в итоге минимизировать перключение контекста.

Ivan
12.09.2017
13:49:56
так pool может регулировать количество потоко
потоков в зависимости от нагрузки
нагрузка низкая - удалит лишние потоки

Google

Ivan
12.09.2017
13:50:15
нагрузка высокая - создаст

Dmitry
12.09.2017
13:50:56
Насчёт комон пулов киньте почитать поподробнее где оно применяется а реальности плиз

Aleksander
12.09.2017
13:51:51

Ivan
12.09.2017
13:52:10
не слышал про common pool
но в java есть дефолтные механизмы создания пулов

Aleksander
12.09.2017
13:52:30

Admin
ERROR: S client not available

Ivan
12.09.2017
13:52:39
ну слова common там нет

Aleksander
12.09.2017
13:52:52
Сорян, метод

Ivan
12.09.2017
13:53:45
а понял

Aleksander
12.09.2017
13:53:46
Возвращает дефолтный пул на которых все эти ваши стримы параллельные выполняются и комплитабл фьючи

Ivan
12.09.2017
13:53:53
но лучше кастомный юзать
ну и вообще ForkJoin только для определенного типа задач

Aleksander
12.09.2017
13:54:58

Ivan
12.09.2017
13:55:49
если ты говоришь про задачу @K_Gregory то мне кажется они пытаются что-то выдумать
что им реально не нужно

Aleksander
12.09.2017
13:56:23

Gregory
12.09.2017
14:00:40
Понятно, что если мы сделаем в конце get(), то всё схлопнется в синхрон.
Хочется весь код оставить асинхронным.
Представь ситуацию, что приходит 1000 запросов, у каждого есть толстая таска, которая сейчас выполняется синхронно (а в ней долгий IO) - по факту забьём все потоки

Aleksander
12.09.2017
14:01:29

Google

Aleksander
12.09.2017
14:02:55

Ivan
12.09.2017
14:03:26

Igor
12.09.2017
14:03:26

Ivan
12.09.2017
14:03:32
и пробрасывайте реквесты туда

Sergey
12.09.2017
14:03:34
да, уже посмотрел. 2 дня назад

Gregory
12.09.2017
14:04:18

Ivan
12.09.2017
14:05:13
Spring reactor
spring batch
akka streams
напишите конвейер и он полностью асинхронно вам перемолет ваши задачи

Aleksander
12.09.2017
14:06:43
В общем я понял, что ты хочешь. Запустить задачу в фильтре(например), а потом в контроллере схлопнуть. Тогда тебе придется эту задачу обернуть во фьючу, далее записать куда-нибудь(в сессию, в аттрибуты реквеста, в principal) и уже в контроллере по надобности вынимать задачу оттуда и делать join

Ivan
12.09.2017
14:06:43
либо напишите свое решение но не зависящее от Servlet стека

Gregory
12.09.2017
14:08:29
В общем, стандартного способа в спринге нет :)

Ivan
12.09.2017
14:09:06
при чем тут спринг вы придумали задачу
которая 100% вам не нужна
и пытаетесь ее решить
но виноват спринг

Gregory
12.09.2017
14:10:52
Нам по смыслу async / await шарповый нужен.