Подтвердить что ты не робот

Должен ли я переопределить стандартный ExecutionContext?

При использовании фьючерсов в scala поведение по умолчанию заключается в использовании контекста выполнения Implicits.global по умолчанию. Кажется, что это по умолчанию делает один поток доступным для каждого процессора. В более традиционном многопоточном веб-приложении это кажется плохим дефолтом, когда фьючерсы выполняют задачу, такую ​​как ожидание в базе данных (в отличие от некоторой связанной задачи с процессором).

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

4b9b3361

Ответ 1

Вместо того, чтобы думать об этом как о переопределении контекста выполнения по умолчанию, почему бы не спросить: "Должен ли я использовать несколько контекстов выполнения для разных вещей?" Если бы этот вопрос, тогда мой ответ был бы да. Там, где я работаю, мы используем Akka. В нашем приложении мы используем контекст исполнения Akka по умолчанию для неблокирующих функций. Тогда, поскольку в настоящий момент нет хорошего не блокирующего драйвера jdbc, все наши блокирующие SQL-вызовы используют отдельный контекст выполнения, где у нас есть поток для каждого подхода к подключению. Сохранение основного сценария выполнения (пул соединений вил) без блокировки приводит к значительному увеличению пропускной способности для нас.

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

Ответ 2

"Правильный" ответ заключается в том, что ваши методы, которые должны использовать ExecutionContext, требуют в своей сигнатуре ExecutionContext, поэтому вы можете предоставить ExecutionContext (s) из "внешнего" для управления исполнением на более высоком уровне.

Ответ 3

Да, создание и использование других контекстов выполнения в вашем приложении, безусловно, хорошая идея.

Контексты выполнения будут модулировать вашу модель concurrency и изолировать различные части вашего приложения, так что если что-то пойдет не так в части вашего приложения, другие части будут менее затронуты этим. Чтобы рассмотреть ваш пример, у вас будет другой контекст выполнения для конкретных операций с БД, а другой, например, для обработки веб-запросов.

В этой презентации Jonas Boner этот шаблон называется созданием "переборки" в вашем приложении для большей стабильности и отказоустойчивости.

Я должен признать, что я не очень много слышал об использовании контекста выполнения. Тем не менее, я вижу, что этот принцип применяется в некоторых рамках. Например, Play будет использовать разные контексты выполнения для разных типов заданий, и они при желании могут разделить ваши задачи на разные пулы: Play Thread Pools

Средство промежуточного уровня Akka также предлагает разбивать ваше приложение на разные контексты для разных зон concurrency в вашем приложении. Они используют концепцию Dispatcher, которая является контекстом выполнения на батареях.

Кроме того, для большинства операторов в библиотеке scala concurrency требуется контекст выполнения. Это по дизайну, чтобы предоставить вам необходимую гибкость при модуляции вашего приложения concurrency -wise.