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

FPConf 2016

FPConf 2016

Practical akka streams

Avatar for Alexey Romanchuk

Alexey Romanchuk

December 03, 2016

Other Decks in Programming

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)