Но в статье сплошные антипаттерны на тему как делать не надо, подаются под соусом "вот так правильно"
Возможно мне стоило указать это прямо, но статья как раз о моих ошибках и о том, как делать не надо :) Executors.newCachedThreadPool() использован исключительно для контраста с fixedThreadPool()
Если есть необходимость создать свой собтсвенный пул потоков в spring, то делать это небходимо через его контекст. Тогда не надо будет думать над тем чтобы его завершить и делать костыли вида - @PreDestroy
В том-то и дело, что если мы говорим об ExecutorService, то graceful shutdown для него нужно прописывать руками безотносительно того, внедряется ли он через контекст или напрямую (как в моём примере). То, о чём вы говорите - это TaskExecutor, вот он управляется контекстом и гарантирует правильное завершение всех подзадач. В моём случае ExecutorService использовался по одной причине - я просто лучше знаю его АПИ, что было важно в условиях цейтнота.
Spring уже сам все умеет и не надо делать опять костыли вида - executor.awaitTermination.достаточно добавить настройку (server.shutdown=graceful)
В указанном вами примере речь опять же идёт о ThreadPoolTaskExecutor.
И оффер скорее всего вам не сделали
Оффер дали, но как и написал в первом предложении намерения уходить с текущего места не было, да и по деньгам предлагали сильно меньше желаемого.
1) обычные java CompletableFuture и ассинхроный неблокирующего хттп клиент который уже есть начиная с jdk11
2) spring reactor/webClient
3) coroutines/loom
По пунктам 2 и 3 согласен, по 1 скорее нет, т.к. предложенное вами решение очень громоздкое и трудночитаемое. Если есть сильное стремление использовать реактивщину, то почему бы не использовать reactive feign?
Явно прописан spring-профиль test. Все компоненты, содержащие аннотацию @Scheduled, отключены (через @Profile("!test")). Тесты, в рамках которых нужно проверить логику шедулеров, инжектят сервисы этих шедулеров и дёргают бизнес-логику ручками.
Почему бы не прописать отдельные значения для @Scheduled в application-test.yml?
Решения от Cognitive Technologies. Хотя сам вопрос о "большом и высокотехнологичном проекте" очень расплывчатый. Сейчас и добыча нефти весьма и весьма высокотехнологична, ибо там используется всё: от передовой химии до беспилотников для наблюдения за состоянием трубопроводов.
Ну, идея проистекает прямо из вашей реализации мока. Насколько я понимаю, это не просто заглушка, дающая установленный ответ на установленный запрос, а немного прокси, выполняющий запись в базу и реализующий некоторую логику.
Если вы знакомы с Kafka, то вы знаете, что она не отдает документы, а просто их хранит, грубо говоря
Жадная какая Кафка )
- Прокси работает с реальным сервером — работа с реальными данными всегда важна, поэтому это практически всегда плюс - Мокирование не работает с реальными данными, но позволяет избавиться от зависимости от реального сервера. При этом большинство задач на моках покрывает то, что нельзя решить на реальном серваке
В вашем случае, имхо, есть возможность объединить оба подхода: перехватывать пары запрос-ответ с помощью прокси и складывать в хранилище, откда их возьмёт заглушка. Таким образом у вас появляется 1) постоянно расширяемая база реальных запросов/ответов 2) возможность воспроизводить сбои (берём упавшую пару запрос-ответ и гоняем воспроизводя гипотетическую ошибку)
Ручное тестирование сильно улучшает качество конечного продукта и позволяет находить ошибки, из-за которых дальнейшая разработка может колом встать. ИМХО, лучше в моменте несколько замедлить процессы, получив качественный продукт и равномерной и предсказуемой скоростью разработки, чем резко сорваться с места и влететь в стену.
Для охлаждения остановленных реакторов (особенно остановленных более года назад) нужно мизерное количество воды (в сравнении с обычным режимом), т.к. охлаждающая вода прокачивается в замкнутом контуре.
Станция на время боёв остановлена (уже более года), и до их окончания никто пускать её не будет, соответственно, водозабор если и будут строить, то после войны. По-моему, это предельно очевидно.
Благодарю за развёрнутый комментарий, плюсанул.
Возможно мне стоило указать это прямо, но статья как раз о моих ошибках и о том, как делать не надо :)
Executors.newCachedThreadPool()
использован исключительно для контраста сfixedThreadPool()
В том-то и дело, что если мы говорим об
ExecutorService
, то graceful shutdown для него нужно прописывать руками безотносительно того, внедряется ли он через контекст или напрямую (как в моём примере). То, о чём вы говорите - этоTaskExecutor
, вот он управляется контекстом и гарантирует правильное завершение всех подзадач. В моём случаеExecutorService
использовался по одной причине - я просто лучше знаю его АПИ, что было важно в условиях цейтнота.В указанном вами примере речь опять же идёт о
ThreadPoolTaskExecutor
.Оффер дали, но как и написал в первом предложении намерения уходить с текущего места не было, да и по деньгам предлагали сильно меньше желаемого.
По пунктам 2 и 3 согласен, по 1 скорее нет, т.к. предложенное вами решение очень громоздкое и трудночитаемое. Если есть сильное стремление использовать реактивщину, то почему бы не использовать reactive feign?
Ожидаю плодотворной дискуссии :)
На тему "какой поток что выполняет" есть неплохой доклад Сергея Куксенко https://www.youtube.com/watch?v=W7iK74YA5NM
Реактивщину я не очень хорошо знаю, увы, использовал блокирующее решение. И так еле уложился в 1 час
Точно нет, я бы запомнил и добавил в статью. А как бы вы семафором ограничили?
Спасибо, исправил
Спорное утверждение, да и заметка немного о другом :)
Явно прописан spring-профиль test. Все компоненты, содержащие аннотацию
@Scheduled
, отключены (через@Profile("!test")
). Тесты, в рамках которых нужно проверить логику шедулеров, инжектят сервисы этих шедулеров и дёргают бизнес-логику ручками.Почему бы не прописать отдельные значения для
@Scheduled в application-test.yml?
Вопрос в том, как от него теперь отпочковаться?
Насколько я понимаю, там коммерция. Компетенции и возможности у японцев есть.
С919 с мая уже используется для перевозок, 6 штук уже сделали и останавливаться не собираются.
MRJ же.
Есть ещё китайский "Комак". Также пассажирские самолёты делает "Митсубиси".
Решения от Cognitive Technologies. Хотя сам вопрос о "большом и высокотехнологичном проекте" очень расплывчатый. Сейчас и добыча нефти весьма и весьма высокотехнологична, ибо там используется всё: от передовой химии до беспилотников для наблюдения за состоянием трубопроводов.
Я надеюсь, это был сарказм. Потому что цветных фото того же Вильгельма II как-то тоже не сделали.
Ну, идея проистекает прямо из вашей реализации мока. Насколько я понимаю, это не просто заглушка, дающая установленный ответ на установленный запрос, а немного прокси, выполняющий запись в базу и реализующий некоторую логику.
Спасибо за статью!
Жадная какая Кафка )
В вашем случае, имхо, есть возможность объединить оба подхода: перехватывать пары запрос-ответ с помощью прокси и складывать в хранилище, откда их возьмёт заглушка. Таким образом у вас появляется
1) постоянно расширяемая база реальных запросов/ответов
2) возможность воспроизводить сбои (берём упавшую пару запрос-ответ и гоняем воспроизводя гипотетическую ошибку)
Обращайтесь :). Я хоть и давно работаю в отрасли, но тоже открыл для себя много нового в процессе написания статьи
Ручное тестирование сильно улучшает качество конечного продукта и позволяет находить ошибки, из-за которых дальнейшая разработка может колом встать. ИМХО, лучше в моменте несколько замедлить процессы, получив качественный продукт и равномерной и предсказуемой скоростью разработки, чем резко сорваться с места и влететь в стену.
Работающая станция != работающий реактор.
Для охлаждения остановленных реакторов (особенно остановленных более года назад) нужно мизерное количество воды (в сравнении с обычным режимом), т.к. охлаждающая вода прокачивается в замкнутом контуре.
Станция на время боёв остановлена (уже более года), и до их окончания никто пускать её не будет, соответственно, водозабор если и будут строить, то после войны. По-моему, это предельно очевидно.