Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Практическое применение Akka Streams

Avatar for devday2gis devday2gis
January 23, 2017

Практическое применение Akka Streams

Несколько жизненных примеров использования Akka Streams

Avatar for devday2gis

devday2gis

January 23, 2017

Other Decks in Technology

Transcript

  1. 3

  2. • Знаете синтаксис Scala • Знакомы со стандартной библиотекой Scala

    • Слышали про Reactive Streams • Видели Akka Streams* 5 О вас
  3. T

  4. • Реализуют спецификацию Reactive Streams • Основаны на Akka •

    Умеют Backpressure • Статически типизированы 8 Akka Streams
  5. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  6. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  7. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  8. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  9. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  10. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  11. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  12. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  13. 11 Source Source.single(1)
 Source.failed(new Exception())
 Source.empty[Int]
 
 Source.repeat(1)
 Source.fromIterator(() =>

    Iterator(1, 2, 3))
 Source.cycle(() => Iterator(1, 2, 3))
 
 Source.tick(1 second, 100 millis, ())
  14. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  15. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  16. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  17. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  18. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  19. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  20. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  21. 13 Flow Flow[Int].map(identity)
 Flow[Int].mapAsync(10)(Future.successful)
 Flow[Int].mapAsyncUnordered(10)(Future.successful)
 
 Flow[Int].filter(_ % 2 ==

    0)
 Flow[Int].collect {
 case n if n % 2 == 0 => n
 } Flow[Int].take(10)
 Flow[Int].takeWhile(_ > 10)
 Flow[Int].drop(10)
 Flow[Int].dropWhile(_ > 10)
  22. • Прочитать с хадупа логи транзакций и найти там 100

    примеров фродных транзакций 16 Задача List Files API Read Line Result
  23. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  24. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  25. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  26. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  27. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  28. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  29. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  30. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  31. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  32. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  33. 17 Наивная реализация def checkFraud(in: String): Future[Option[TransactionId]] = ??? val

    result: List[TransactionId] = (for {
 file <- hdfs.listStatusIterator(path)
 if file.isFile
 line <-fromInputStream(fs.open(file.getPath)).getLines()
 resultOpt = Await.result(checkFraud(line), 10 seconds)
 result <- resultOpt
 } yield result) .take(100).toList
  34. • Не терять лишнего времени на скачивание • Параллельные запросы

    к сервису • Не превышать ограничения в 10 запросов в секунду 19 Требования
  35. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  36. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  37. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  38. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  39. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  40. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  41. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  42. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  43. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  44. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  45. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  46. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  47. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  48. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  49. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  50. 21 Красивый код на стримах val stream =
 Source
 .fromIterator

    { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  51. 29 Sources case object NotUsed def single[T](element: T) def empty[T]

    def failed[T](cause: Throwable) def repeat[T](element: T) def fromIterator[T](f: () => Iterator[T]) def cycle[T](f: () => Iterator[T])
  52. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  53. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  54. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  55. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  56. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  57. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  58. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  59. 30 Sinks def ignore: Sink[Any, Future[Done]] def foreach[T](f: T =>

    Unit): Sink[T, Future[Done]] def head[T]: Sink[T, Future[T]] def headOption[T]: Sink[T, Future[Option[T]]] def fold[U, T](z: U)(f: (U, T) => U): Sink[T, Future[U]] def reduce[T](f: (T, T) => T): Sink[T, Future[T]]
  60. 31 Композиция val source: Source[Int, NotUsed] = Source.single(1)
 val sink:

    Sink[Any, Future[Done]] = Sink.ignore
 
 val s1: RunnableGraph[NotUsed] = source.to(sink)
 
 val s2: RunnableGraph[Future[Done]] =
 source.toMat(sink)(Keep.right)
 
 val s3: RunnableGraph[(NotUsed, Future[Done])] =
 source.toMat(sink)(Keep.both)

  61. 31 Композиция val source: Source[Int, NotUsed] = Source.single(1)
 val sink:

    Sink[Any, Future[Done]] = Sink.ignore
 
 val s1: RunnableGraph[NotUsed] = source.to(sink)
 
 val s2: RunnableGraph[Future[Done]] =
 source.toMat(sink)(Keep.right)
 
 val s3: RunnableGraph[(NotUsed, Future[Done])] =
 source.toMat(sink)(Keep.both)

  62. 31 Композиция val source: Source[Int, NotUsed] = Source.single(1)
 val sink:

    Sink[Any, Future[Done]] = Sink.ignore
 
 val s1: RunnableGraph[NotUsed] = source.to(sink)
 
 val s2: RunnableGraph[Future[Done]] =
 source.toMat(sink)(Keep.right)
 
 val s3: RunnableGraph[(NotUsed, Future[Done])] =
 source.toMat(sink)(Keep.both)

  63. 31 Композиция val source: Source[Int, NotUsed] = Source.single(1)
 val sink:

    Sink[Any, Future[Done]] = Sink.ignore
 
 val s1: RunnableGraph[NotUsed] = source.to(sink)
 
 val s2: RunnableGraph[Future[Done]] =
 source.toMat(sink)(Keep.right)
 
 val s3: RunnableGraph[(NotUsed, Future[Done])] =
 source.toMat(sink)(Keep.both)

  64. 31 Композиция val source: Source[Int, NotUsed] = Source.single(1)
 val sink:

    Sink[Any, Future[Done]] = Sink.ignore
 
 val s1: RunnableGraph[NotUsed] = source.to(sink)
 
 val s2: RunnableGraph[Future[Done]] =
 source.toMat(sink)(Keep.right)
 
 val s3: RunnableGraph[(NotUsed, Future[Done])] =
 source.toMat(sink)(Keep.both)

  65. 31 Композиция val source: Source[Int, NotUsed] = Source.single(1)
 val sink:

    Sink[Any, Future[Done]] = Sink.ignore
 
 val s1: RunnableGraph[NotUsed] = source.to(sink)
 
 val s2: RunnableGraph[Future[Done]] =
 source.toMat(sink)(Keep.right)
 
 val s3: RunnableGraph[(NotUsed, Future[Done])] =
 source.toMat(sink)(Keep.both)

  66. 33 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] = Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  67. 33 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] = Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  68. 33 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] = Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  69. 33 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] = Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  70. 34 Красивая картинка со схемой List Files API Read Line

    Result run() Future Stream run() Future Stream Future
  71. 37 Красивый код на стримах val source = ZMQSource(context,
 mode

    = ZMQ.PULL,
 timeout = 1 second,
 addresses = List("tcp: //127.0.0.1:12345")
 )
 
 def process(in: ByteString): Future[Int] = ???
  72. 37 Красивый код на стримах val source = ZMQSource(context,
 mode

    = ZMQ.PULL,
 timeout = 1 second,
 addresses = List("tcp: //127.0.0.1:12345")
 )
 
 def process(in: ByteString): Future[Int] = ???
  73. 37 Красивый код на стримах val source = ZMQSource(context,
 mode

    = ZMQ.PULL,
 timeout = 1 second,
 addresses = List("tcp: //127.0.0.1:12345")
 )
 
 def process(in: ByteString): Future[Int] = ???
  74. 37 Красивый код на стримах val source = ZMQSource(context,
 mode

    = ZMQ.PULL,
 timeout = 1 second,
 addresses = List("tcp: //127.0.0.1:12345")
 )
 
 def process(in: ByteString): Future[Int] = ???
  75. 38 Красивый код на стримах val stream = source
 .mapAsync(10)(process)


    .toMat(Sink.last)(Keep.right)
 
 val result: Future[Int] = stream.run()
 result.onComplete(_ => "We are done here")

  76. 38 Красивый код на стримах val stream = source
 .mapAsync(10)(process)


    .toMat(Sink.last)(Keep.right)
 
 val result: Future[Int] = stream.run()
 result.onComplete(_ => "We are done here")

  77. 38 Красивый код на стримах val stream = source
 .mapAsync(10)(process)


    .toMat(Sink.last)(Keep.right)
 
 val result: Future[Int] = stream.run()
 result.onComplete(_ => "We are done here")

  78. 38 Красивый код на стримах val stream = source
 .mapAsync(10)(process)


    .toMat(Sink.last)(Keep.right)
 
 val result: Future[Int] = stream.run()
 result.onComplete(_ => "We are done here")

  79. 38 Красивый код на стримах val stream = source
 .mapAsync(10)(process)


    .toMat(Sink.last)(Keep.right)
 
 val result: Future[Int] = stream.run()
 result.onComplete(_ => "We are done here")

  80. 41 Проблема остановки val stream = source
 .mapAsync(10)(process)
 .toMat(Sink.last)(Keep.right)
 


    val result: Future[Int] = stream.run()
 result.onComplete(_ => "We are done here")

  81. 43 Проблема остановки trait Control {
 /**
 * Disconnect the

    underlying ZMQ socket, deliver the remaining data and finally close the socket.
 */
 def gracefulStop(): Unit
 }
  82. 44 Проблема остановки val source: Source[ByteString, Control] = ??? val

    stream: RunnableGraph[(Control, Future[Int])] = source
 .mapAsync(10)(process)
 .toMat(Sink.head)(Keep.both)
 
 val (control: Control, result: Future[Int]) = stream.run()
 result.onComplete(_ => "We are done here")
 control.gracefulStop()
  83. 44 Проблема остановки val source: Source[ByteString, Control] = ??? val

    stream: RunnableGraph[(Control, Future[Int])] = source
 .mapAsync(10)(process)
 .toMat(Sink.head)(Keep.both)
 
 val (control: Control, result: Future[Int]) = stream.run()
 result.onComplete(_ => "We are done here")
 control.gracefulStop()
  84. 44 Проблема остановки val source: Source[ByteString, Control] = ??? val

    stream: RunnableGraph[(Control, Future[Int])] = source
 .mapAsync(10)(process)
 .toMat(Sink.head)(Keep.both)
 
 val (control: Control, result: Future[Int]) = stream.run()
 result.onComplete(_ => "We are done here")
 control.gracefulStop()
  85. 44 Проблема остановки val source: Source[ByteString, Control] = ??? val

    stream: RunnableGraph[(Control, Future[Int])] = source
 .mapAsync(10)(process)
 .toMat(Sink.head)(Keep.both)
 
 val (control: Control, result: Future[Int]) = stream.run()
 result.onComplete(_ => "We are done here")
 control.gracefulStop()
  86. 44 Проблема остановки val source: Source[ByteString, Control] = ??? val

    stream: RunnableGraph[(Control, Future[Int])] = source
 .mapAsync(10)(process)
 .toMat(Sink.head)(Keep.both)
 
 val (control: Control, result: Future[Int]) = stream.run()
 result.onComplete(_ => "We are done here")
 control.gracefulStop()
  87. 44 Проблема остановки val source: Source[ByteString, Control] = ??? val

    stream: RunnableGraph[(Control, Future[Int])] = source
 .mapAsync(10)(process)
 .toMat(Sink.head)(Keep.both)
 
 val (control: Control, result: Future[Int]) = stream.run()
 result.onComplete(_ => "We are done here")
 control.gracefulStop()
  88. • Emit элемента • Завершение • Ошибка • Backpressure •

    Отмена 47 Что нужно знать про stages
  89. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  90. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  91. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  92. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  93. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  94. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  95. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  96. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  97. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  98. 48 Свой Source val s: Source[Int, ActorRef] =
 Source.actorPublisher[Int](Props(new MySourceActor))


    
 class MySourceActor extends ActorPublisher[Int] {
 override def receive: Receive = {
 case ActorPublisherMessage.Request(n) =>
 onNext(100)
 onCompleteThenStop()
 onErrorThenStop(new Exception)
 case ActorPublisherMessage.Cancel =>
 context.stop(self)
 }
 }

  99. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  100. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  101. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  102. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  103. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  104. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  105. 49 Reactive Zmq case object GracefulStop
 case object DeliverMore
 class

    MySourceActor(addr: String) extends ActorPublisher[Array[Byte]] {
 var conn: ZMQ.Socket = ???
 
 override def preStart(): Unit = {
 conn.connect(addr)
 }
 
 override def postStop(): Unit = {
 conn.disconnect(addr)
 }

  106. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  107. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  108. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  109. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  110. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  111. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  112. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  113. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  114. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  115. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  116. 50 Reactive Zmq override def receive: Receive = {
 case

    ActorPublisherMessage.Request(_) | DeliverMore =>
 Option(conn.recv()) match {
 case Some(msg) =>
 onNext(msg)
 if(totalDemand > 0) self ! DeliverMore
 case None => self ! DeliverMore
 }
 case ActorPublisherMessage.Cancel | GracefulStop =>
 conn.disconnect(addr)
 onCompleteThenStop()
 }

  117. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  118. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  119. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  120. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  121. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  122. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  123. 51 Reactive Zmq val source: Source[Array[Byte], Control] =
 Source.actorPublisher[Array[Byte]](
 Props(new

    MySourceActor( ???))
 ).mapMaterializedValue { ref =>
 new Control {
 override def gracefulStop() = ref ! GracefulStop
 }
 }
  124. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  125. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  126. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  127. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  128. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  129. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  130. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  131. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  132. 52 Свой Sink val s = Sink.actorSubscriber[Int](Props(new MySinkActor))
 
 class

    MySinkActor extends ActorSubscriber {
 override def receive: Receive = {
 case ActorSubscriberMessage.OnNext =>
 cancel()
 request(100)
 case ActorSubscriberMessage.OnComplete =>
 case ActorSubscriberMessage.OnError =>
 }
  133. • Более простая технология не подходит • Backpressure • Упорядоченные

    потоки • Локальность • Фиксированная топология 56 Когда стоит использовать
  134. • Документация Akka Streams • Альпака • reactive-zmq • reactive-kafka

    • Первое видео про Akka Streams • Слайды этой презентации - goo.gl/F7EYoE 57 Ссылки
  135. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  136. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  137. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  138. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  139. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  140. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  141. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  142. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  143. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  144. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  145. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  146. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  147. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  148. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  149. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)

  150. 85 Красивый код на стримах val stream: RunnableGraph[Future[List[TransactionId]]] =
 Source


    .fromIterator { () => hdfs.listStatusIterator(path) }
 .filter(_.isFile)
 .flatMapConcat { file =>
 val s = fromInputStream(hdfs.open(file.getPath))
 Source.fromIterator(() => s.getLines())
 }
 .throttle(10, 1 second, 0, ThrottleMode.Shaping)
 .mapAsyncUnordered(50)(checkFraud)
 .collect { case Some(value) => value }
 .take(100)
 .fold(List.empty[TransactionId])(_ :+ _)
 .toMat(Sink.head)(Keep.right)