Scala concurrency Flashcards
почему mixing ExecutionContext это плохо - например одновременное использование execusion context global and другого своего execusion context ? ( например вы забыли про свой execusion context и случайно авто импортировали глобал чем это может грозить ) ???
в Принципе если ты знаешь что делаешь в этом нет ничего плохого ( если у тебя достаточно сеньерные знания ) в противном случае всякие моменты с async bondaries между execution context могут привести к неожиданному поведению потоков
what future state do u know ?
- not complete yet , 2. complete success ; 3. complete failure
если взять фьюче ф1 = Фьюче ( спать 1 с и верни 10 )
и взять ф2 = ф1.мап( _ * 10 )
что вернется ? ошибка ? исключение или может ф2 будет ждать 1 секунду ?
ошибка не вернется ф2 не заблокируется мап - не будет блокироваться
вернется ссылка на ф1 и на ф2 и когда ф1 закончить спать то ф2 немедленно вычислиться
исключения тоже не будет и ошибки не будет .
method .value what will be return type
Option[Try[VALUE]] - 5 min ( 27. Future and Promises )
какой метод дожидается выполнения фьюча
onComplete 6-39 min ( 27 … )
какие методы могут сразу вернуть результат future ?
Future.successful ( … ) ; .failed ; fromTry ….
при это для выполнения этих методов не нужен execusion context они исполняться в том же thread что и основная программа
3м ( 103 )
что вы знаете про fallback ? как можно recover from failure ?
14 min ( 28 … ) … бла бла рассказать про recovery vs recoverWith vs FallbackTo()
3и разных способа - 1) самый простой это использовать fallbackTo method - мы просто в случае если наше фьюче свалилось можем создать новое фьюче и вызвать у него success( И в аргумент отдать то что мы хотим )
2) с помощью метода recover мы можем сделать матч паттерн и в зависимости от типа исключения выдавать то или что-то другое
3) recoverWith ( recover vs recoverWith - по аналогии с map vs flatMap ) - с помощью этого метода мы можем на каждый разный тип исключения возвращать различные новые фьюче
—-
SSA part 3 113.13 - recovering from failures
when it could be useful to block future ?
1 min ( 29 …. ) transaction … back(??) operations … еще раз повторюсь что away пользоваться плохо но … это нормальная практика на самом верхнем уровне программы ( где возле main функции писать подождать секунду или вернуть failure … потому что по мере собирания комюлятивного ответа мы можем композить много много фьюч и может так получиться что что то пойдет не так в этом случае у нас должна быть возможность все отменить через определенный промежуток времени. используем ( await.result( наше фьюча , или отменить все через 10 секунд ( например ))
SSA part 3 110 . 10 - Forcing a Result
почему пользоваться await or just blocking future ( include Thread sleep ) это плохо и где это уместно
уместно в тестах … а вообще это плохо потому что это занимает рабочее время потока из threadpool - что очень сильно уменьшает производительность … у вас может быть 1 млн фьюч но только десяток потоков в определенный момент времени … так же можно это приминять очень осторожно на самом top level of your program
1 м (105 )
Future is eager or lazy ? Почему eager это плохо ? как можно сделать Future lazy
eager - дает меньше контроля над ресурсами такими как память и время CPU … вполне возможно мы не хотим отдавать ресурсы прямо сейчас на какие то дорогие вычисления …
Можно сделать выполнение Future lazy при помощи ключевого слова lazy … ( пока точно не знаю как потом допишу )
https://bluishcoder.co.nz/2006/07/19/scala-futures-and-lazy-evaluation.html - как то так можно - танцуя с бубном
Как можно отменить выполнение Future ? - представьте что пришел клиент на сайт и заказал поиск вк id по фотографии - фото задействует ИИ что очень дорого + база данных дергается что тоже дорого … он подождал 10 секунд и не дожидаясь вышел … а наше future Будет считаться еще секунд 50 что дорого хотелось бы его отменить … что делать ?
Future так просто отменять нельзя к сожалению для этого есть специальные примитивы в cats - effect и в ZIO … но можно отменить если использовать execusion context from actor system ( если спросят как именно скажешь что точно не знаешь ты просто читала об этом хотела закодить мини демо на этот счет но как то руки не дошли )
назовите другие ( помимо map and flatMap - не блокирующие операции для фьюче )
1) .collect - в случае с фьюче можно работать как при использовании матч паттерна …
- можно например применять когда у нас фьюче от any -> с помощью коллект можно сделать из него future[Int]
2) .filter
3) .transform - позволяет более коротко записывать что делать с success or failure без матч паттерна ( в одном method call )
4) .andThen - позволяет делать side effect ( например печатать что ниб в лог или открыть / закрыть файл ) после того как фьюче вернет значение
по работе очень похож на .onComplete
5) .foreach -> только работает on success и тоже позволяет фигачить сайд эффект ( возвр тип Unit )
если надо вызывать .foreach на failure то тогда надо future.failed.foreach
http://prntscr.com/oj0cqh
–
SSA part 3 111.11 - Other future operations
SSA part 3 112.12 More operations
.sequence vs .traverse ??? чем отличаются ?
traverse в себе комбинирует sequence + map
- 14 - Dealing with Multiple Futures
какие другие future sequence операции вы знаете
firstCompletedOf - принимает список фьюч и возвращает результат того фьюче который быстрее всех закончил работу .
что будет с другими фьючами ? они где то на бекграунде продолжат работать ? - ответ - нет они отменяться ( это важно потому что обычно фьюча is not cancelable )
надо помнить что это относительно дорогой метод потому что сразу много фьюч заряжаются чтобы получить один результат
так же есть .foldLeft and reduceLeft - которые работают практически одинаково но reduce - без начального значения ( аккумулятора как в случае с фолд лефт )
- 15 - Other Future Sequence Operations
как сделать так чтобы из нескольких фьюч взять то которое быстрее исполниться а остальные отменить ?
firstCompletedOf
что вы знаете про broken promise ?
Работая с фьюче через промес дает больше контроля над вычислением которые произходит в другом потоке ( потоках ) - в том числе когда вычисление приводит к exception - ну … работая через промес можно на каждый этап вычисление отдовать свой тип эксепшен таким образом лучше знать что где сломалось
- 17 - A Broken Promise
какой самый близкий аналог скала фьюча в Java ?
completableFuture …
_____
SSA part 3 118. 18 - Working with Java’s Futures
как можно конвертировать java future в скала future ? в 2х словах как это работает ( через что ) ?
можно работать с java code через Import scala.compat.java8.FutureConverters._
и конечно все это не блокирующее фьюче
это работает через promise как раз
_____
SSA part 3 118. 18 - Working with Java’s Futures
что вы знаете про future patterns - batching ?
это оптимизационная техника позволяющая дизайнить и регулировать трейд офф : с одной стороны кол-во фьюч одновременно запущенных с другой стороны потребление ram / cpu
___
SSA part 3 119. 19 - Future Patterns - Batching
Какие оптимизационные техники вы знаете для работы с фьюче ( как сделать трейд оф между количеством фьюч работающих одновременно и memory /cpu consumption ) ?
идея такая, что мы выбираем кол-во фьюч которые будут работать одновременно ( например 100 ) и не начинаем новую партию из 100 фьюч пока не завершиться предыдущая ( batch ) партия. Для этого мы используем такие методы как sequence / traversable and foldleft , flatmap / forcomprehension , grouped
см слайды по ссылкам
- 20 - foldLeft and flatMap
если у нас коллекция из неизвестного количества фьюч в ней, но нам очень хочется использовать for comprehension для того чтобы фильтровать и делать какую то другую сложную логику с фьючами и их комбинацией, что нам можно сделать
можно взять за основу future batch pattern, модифицировать его слегка и таким образом получить желаемую функциональность.
Представьте ситуацию… вы просите через фьюче у какого то внешнего сервиса данные, но в ответ приходит ошибка при этом вы знаете что в среднем данные все таки приходят либо в среднем на 4й или на 10й раз. расскажите как вы будете решать эту проблему ?
future pattern - retrying
есть naive имплементация и нормальная
в чем проблема наивного подхода ? - если 100 раз надо попробовать ??? код повторение вообщем проблема
для нормального подхода будет использовать рекурсию и call by name( если я не потаю ) ( => ) и recoverWith
так же есть retry with backOff
там в имплиментации scala async Timer ; seq with времеными интервалами , promise , TimerTask , .flattern ,
___
121. 21 - Future Patterns - Retrying
- 22 - Retrying (naive) - 124
Какие альтернативы future вы знаете ?
Monix Task , some premitive from cats - effects and ZIO , twitter Future
вопрос что такое промис и все такое
10 min ( 29 ) - если коротко то это способ общения между различными threads - можно например создать промис из него создать future и в другом потоке положить в этот промис значение которое автоматически появиться в ранее созданом future и можно вытащить это значение через OnComplete …
Можно сказать что future отвечает за чтение результата который создается в другом потоке
а Промис отвечает за запись этого результата который потом можно будет вытащить в настоящее ( прочитать ) через ранее созданное фьюче
промис чем то похож на своебразные актор по своему назначению
а взаимодействие между фьюче и промис на ask паттерн в akka actor
Пример с подсчетом слов
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.util.{Failure, Success}
object AppFutureMemory extends App {
println(“ - sync version “)
// 1 val
listString: List[String] = List(“vika”, “murlishka”, “zaika”, “homa”, “pechen’ka”) println(listString) println(listString.map(e => e.length).sum)