Рахимжанов Тимур
Вам нужно выкопать во дворе бассейн
Вы взяли лопату и копаете. Это однопоточная работа
Параллельное исполнение подразумевает наличие
более одного
вычислительного устройства
(например, процессора),
которые будут одновременно выполнять несколько задач
Пока вы копаете бассейн, Вася копает канаву под водопровод.
Никто никому не мешает. Это параллельное исполнение
Это один из способов реализации исполнения путем выделения
абстракции "рабочего потока" (worker thread)
Вы пригласили друга Васю и копаете вместе,
периодически задевая друг-друга лопатами
Подразумевает, что операция может быть выполнена
кем-то на стороне:
удаленным веб-узлом, сервером или другим устройством
за пределами текущего вычислительного устройства
Вы пригласили бригаду землекопов, а сами отдыхаете.
Когда бригада все сделает, к вам придут за деньгами.
Это асинхронная работа
Futures provide a way to reason about performing
many operations in parallel – in an efficient and non-blocking way.
(c) documentation
Futures provide a way to reason about performing
many operations in parallel – in an efficient and non-blocking way.
(c) documentation
val getTopAuthors: Future[Seq[Author]] = for {
books: Seq[Book] <- bookService.getTop10()
authorIds: Seq[String] = books.map(_.authorId)
authors: Seq[Author] <- authorService.getByIds(authorIds)
} yield {
authors
}
val lst = someList()
lst.map(hardElementOperation(_))
lst.par.map(hardElementOperation(_))
private def boilWater(): ZIO[Any, Nothing, Unit] = {...}
private def fryEggs(): ZIO[Any, Nothing, Unit] = {...}
def makeBreakfast: ZIO[Any, Nothing, Unit] = for {
waterFiber <- boilWater()
eggsFiber <- fryEggs()
} yield ()
private def boilWater(): ZIO[Any, Nothing, Unit] = {...}
private def fryEggs(): ZIO[Any, Nothing, Unit] = {...}
def makeBreakfast: ZIO[Any, Nothing, Unit] = for {
waterFiber <- boilWater().fork
eggsFiber <- fryEggs().fork
} yield ()
private def boilWater(): ZIO[Any, Nothing, Unit] = {...}
private def fryEggs(): ZIO[Any, Nothing, Unit] = {...}
def makeBreakfast: ZIO[Any, Nothing, Unit] = for {
waterFiber <- boilWater().fork
eggsFiber <- fryEggs().fork
_ <- waterFiber.zip(eggsFiber).await
} yield ()
def task = for {
fn <- ZIO.fiberId.map(_.threadName)
_ <- ZIO.debug(s"$fn starts a long running task")
_ <- ZIO.sleep(1.minute)
_ <- ZIO.debug("done!")
} yield ()
def run = for {
f <- task
.onInterrupt(ZIO.debug(s"Task interrupted while running"))
.fork
_ <- f.interrupt
} yield ()
for {
fiber <- ZIO.attemptBlocking {
while (true) {
Thread.sleep(1000)
println("Doing some blocking operation")
}
}.ensuring(
Console.printLine("End of a blocking operation").orDie
).fork
_ <- fiber.interrupt.schedule(
Schedule.delayed(
Schedule.duration(1.seconds)
)
)
} yield ()
ZManaged[R, E, A] - это управляемый ресурс,
который требует R и может завершиться сбоем с E значением
или завершиться успешно с A
Это структура данных, которая инкапсулирует получение и
высвобождение ресурса, который может быть использован
путем вызова метода use ресурса.
Ресурс будет автоматически захвачен до использования и автоматически освобожден после использования
val managed = ZManaged.make(acquire)(release)
def printFirstLine(file: String): ZIO[Console, Throwable, Unit] = {
def acquire(file: String) = ZIO.effect(
new BufferedReader(new FileReader(file))
)
def release(reader: BufferedReader) = ZIO.effectTotal(reader.close())
ZManaged.make(acquire(file))(release).use { reader =>
putStrLn(reader.readLine())
}
}
Каждый ZIO эффект может быть преобразован к ZManaged с помощью ZManaged.fromEffect или ZIO#toZManaged_
val managedHello = ZManaged.fromEffect(putStrLn("Hello, World!"))
val managedHello_ = putStrLn("Hello, World!").toManaged_
Если ресурс реализовал AutoClosable интерфейс, мы можем легко создать ZManaged из него, используя ZManaged.fromAutoClosable конструктор:
ZManaged.fromAutoCloseable(ZIO.effect(
new FileInputStream("file.txt")
))
ZManaged.fromAutoCloseable(ZIO.effect(
fromResource("file.txt")
))
ZManaged.fromAutoCloseable(ZIO.effect(
fromFile("file.txt")
))
def firstLine(file: String): ZIO[Console, Throwable, Unit] =
ZManaged
.fromAutoCloseable(ZIO.effect(fromFile(file)))
.use { reader =>
putStrLn(reader.bufferedReader().readLine())
}
Если наш управляемый ресурс может быть действительным после освобождения ресурсов, мы можем преобразовать этот ZManaged в ZIO эффект, вызвав ZManaged#useNow
Предположим, мы собираемся сделать управляемый ресурс долгоживущим. ZManaged#useForever преобразует ZManaged в ZIO эффект, который будет доступен вечно