KEMBAR78
Concurrent Application Development using Scala | PPTX
Concurrent Application
Development using Scala
Sergei Semenchuk
https://github.com/binjip978/ConcTalk
FP 101
def withdrawMoney(user: String,
password: String, amount: Int): Money = {
// some logic
Money(amount)
}
def buyBook(name: String, cash: Money): Book = {
// some logic
Book("Functional Programming in Scala")
}
val cash = withdrawMoney("user1", "password2", 100)
val book = buyBook("Functional Programming in Scala", cash)
println(book)
trait Try[+T]
case class Success[+T](value: T) extends Try[T]
case class Failure(e: Throwable) extends Try[Nothing]
val success = Success(100)
success match {
case Success(v) => println(v)
case Failure(e) => println(s"Error: $e")
}
val v = Try {
if (scala.util.Random.nextBoolean() == true) 12
else 1 / 0
}
v match {
case Success(v) => println(v)
case Failure(e) => println("Error!")
}
def withdrawMoney(user: String,
password: String, amount: Int): Try[Money] = {
Try(Money(amount))
}
def buyBook(name: String, cash: Money): Try[Book] = {
Try(Book("Functional Programming in Scala"))
}
withdrawMoney("user1", "password2", 100) match {
case Success(cash) => {
buyBook("Functional Programming in Scala", cash) match {
case Success(book) => println(book)
case Failure(e) => println(s"Error occurred: $e")
}
}
case Failure(e) => println(s"Error occurred: $e")
}
case class Money(amount: Int)
case class Book(title: String)
def withdrawMoney(user: String, password:
String, amount: Int): Try[Money] = {
// some logic
Try(Money(amount))
}
def buyBook(name: String, cash: Money): Try[Book] = {
// some logic
Try(Book("Functional Programming in Scala"))
}
for {
cash <- withdrawMoney("user1", "password2", 100)
book <- buyBook("Functional Programming in Scala", cash)
} println(book)
case class Money(amount: Int)
case class Book(title: String)
def withdrawMoney(user: String, password:
String, amount: Int): Try[Money] = {
// some logic
Try(Money(amount))
}
def buyBook(name: String, cash: Money): Try[Book] = {
// some logic
Try(Book("Functional Programming in Scala"))
}
val book = withdrawMoney("user1", "password2", 100)
.flatMap(cash => buyBook("Functional Programming in Scala", cash))
book.foreach(b => println(b))
}
trait Option[+A]
case class Some[+A](v: A) extends Option[A]
case object None extends Option[Nothing]
def unit[A](v: A): Option[A] = {
Some(v)
}
def flatMap[A, B](op: Option[A])(f: A => Option[B]): Option[B]
= op match {
case Some(v) => f(v)
case None => None
}
def map[A, B](op: Option[A])(f: A => B): Option[B] = {
flatMap(op)(x => unit(f(x)))
}
The Four Essential Effects In Programming
One Many
Synchronous T/Try[T] Iterable[T]
Asynchronous Future[T] Observable[T]
Asynchronous Programming with
Futures
and Promises
//def apply[T](b: =>T)(implicit e: ExecutionContext): Future[T]
val f = Future { println("Hello World!") }
println(f.isCompleted)
Thread.sleep(1000)
println(f.isCompleted)
def getUrlSpec(): Future[List[String]] = Future {
val url = "http://www.w3.org/Addressing/URL/url-spec.txt"
val f = scala.io.Source.fromURL(url)
try {
f.getLines().toList
} finally {
f.close()
}
}
def find(lines: List[String], keyword: String):String = {
lines.zipWithIndex.collect {
case (line, n) if (line.contains(keyword)) => (n, line)
} mkString("n")
}
val f = getUrlSpec()
f.foreach { case (lines) => println(find(lines, “telnet")) }
Thread.sleep(5000)
val f: Future[Int] = Future { 1 / 0 }
f onComplete {
case Success(v) => println("Surprise!")
case Failure(e) => println(s"Error: $e")
}
Thread.sleep(1000)
val f1: Future[Int] = Future { 1345 }
val f2: Future[Int] = Future { 2356 }
val f3: Future[Int] = Future { 4563 }
val comp1: Future[Int] = f1.flatMap(v1 => f2.flatMap(v2 =>
f3.map(v3 => v1 + v2 + v3)))
val comp2: Future[Int] = for {
v1 <- f1
v2 <- f2
v3 <- f3
} yield v1 + v2 + v3
//comp1 === comp2
comp1.onSuccess { case(x: Int) => println(x) }
comp2.onSuccess { case(x: Int) => println(x) }
Thread.sleep(1000)
}
val f1 = Future { 1 }
val f2 = Future { 1 / 0 }
val f3 = Future { 2 }
val c = for {
v1 <- f1
v2 <- f2
v3 <- f3
} yield v1 + v2 + v3
c onComplete {
case Success(v) => println(v)
case Failure(e) => println(s"error $e")
}
Thread.sleep(1000)
def getRandonName = Future { "John" }
def getIdByName(name: String) = Future { 12 }
def getDepotIdById(id: Int) = Future { 34 }
def getDepotName(id: Int) = Future { "A depot" }
val f = for {
name <- getRandonName
userId <- getIdByName(name)
depotId <- getDepotIdById(userId)
depotName <- getDepotName(userId)
} yield s"$name from $depotName"
f.onSuccess {
case (v) => println(v)
}
Thread.sleep(1000)
def getUSDQuote = Future { 1.2 }
def getEURQuote = Future { 0.8 }
val p = for {
usd <- getUSDQuote
eur <- getEURQuote
if (eur > usd)
} yield usd
p onFailure { case (e) => println("Error: " + e) }
Thread.sleep(1000)
val f1: Future[Int] = Future { 1 / 0 }
val f2: Future[Any] = f1.recover {
case (exp) => s"error happend: $exp"
}
f2.onComplete {
case Success(v) => println(s"if success: $v")
case Failure(e) => println(s"if failure: $e")
}
Thread.sleep(1000)
val p = Promise[String]
val q = Promise[String]
p.future foreach { case x => println(x)}
q.future.failed foreach { case e => println(s"error: " + e)}
p.complete(Success("Promise complete"))
q.complete(Failure(new Exception))
val z = Promise[Int]
z.future onComplete {
case Success(v) => println(v)
case Failure(e) => println(s"Error: $e")
}
z.complete(Try(1 / 0))
def first[T](xs: List[Future[T]]): Future[T] = {
val p = Promise[T]
for {
x <- xs
} p.tryCompleteWith(x)
p.future
}
val f = first(List(Future{ Thread.sleep(2000);
12 }, Future { new Exception }))
f.foreach { case x => println(x) }
val urlSpecSize = Future {
val url = "http://www.scala-lang.org"
scala.io.Source.fromURL(url).size
}
// how much we should wait until exception
val size = Await.result(urlSpecSize, 10 seconds)
println(size)
Concurrent Programming with
Reactive Extensions
val observable: Observable[String] = Observable.items("A", "B", "C")
observable.subscribe(str => println(str.toLowerCase))
observable.subscribe(str => println(str * 7))
val o: Observable[Long] = Observable.timer(2 second)
o.subscribe(x => println(x))
o.subscribe(x => println(x + 1000))
val ex = new RuntimeException
val observable: Observable[Int] = Observable.items(0, 1, 2) ++
Observable.error(ex) ++
Observable.items(3, 4)
observable.subscribe(
value => println(value),
error => println(s"an error occurred: $error")
)
val countries = List("Germany", "US", "Japan")
val observable = Observable.from(countries)
observable.subscribe(new Observer[String] {
override def onNext(c: String) = println(s"Nice to live in $c”)
override def onError(e: Throwable) = println(“error!!!")
override def onCompleted() = println("That all list!")
})
// def create(f: Observer[T] => Subscription): Observable[T]
val vms = Observable.apply[String] { obs =>
obs.onNext("JVM")
obs.onNext("LLVM")
obs.onNext("Dalvik")
obs.onCompleted()
Subscription
}
vms.subscribe(str => println(str))
}
val f = Future("Future")
val observable = Observable.apply[String] { obs =>
f onComplete {
case Success(v) => {
obs.onNext(v)
obs.onCompleted()
}
case Failure(e) => {
obs.onError(e)
}
}
Subscription
}
observable.subscribe(str => println(str))
def coldObserver(directory: String): Observable[String] = {
Observable.apply[String] { obs =>
val fileMonitor = new FileAlterationMonitor(1000)
val fileObs = new FileAlterationObserver(directory)
val fileListener = new FileAlterationListenerAdaptor {
override def onFileChange(file: java.io.File): Unit = {
obs.onNext(file.getName)
}
}
fileObs.addListener(fileListener)
fileMonitor.addObserver(fileObs)
fileMonitor.start()
Subscription {
fileMonitor.stop()
}
}
}
def hotObserver(directory: String): Observable[String] = {
val fileMonitor = new FileAlterationMonitor(1000)
val fileObs = new FileAlterationObserver(directory)
fileMonitor.addObserver(fileObs)
Observable.apply[String] { obs =>
val fileListener = new FileAlterationListenerAdaptor {
override def onFileChange(file: java.io.File): Unit = {
obs.onNext(file.getName)
}
}
fileObs.addListener(fileListener)
Subscription { fileObs.removeListener(
fileListener) }
}
}
val odds = Observable.interval(0.5 seconds)
.filter(x => x % 2 == 1)
.map(x => s"num $x")
.take(5)
odds.subscribe(str => println(str))
def fetchQuote(): Future[String] = Future {
blocking {
val url = “http://www.iheartquotes.com/api/v1/random?" + "show_permalink=false&show_source=false"
Source.fromURL(url).getLines().mkString
}
}
def fetchQuoteObservable(): Observable[String] = {
Observable.from(fetchQuote())
}
def quotes(): Observable[Observable[String]] = {
Observable.interval(1 second).take(5).map {
n => fetchQuoteObservable().map(txt => s"$n) $txt")
}
}
val concat: Observable[String] = quotes().concat
concat.subscribe(q => println(q)) /
val flatten: Observable[String] = quotes().flatten //
val qs: Observable[String] = for {
n <- Observable.interval(1 second).take(5)
txt <- fetchQuoteObservable()
} yield s"$n) $txt"
qs.subscribe(q => println(q))
def randomQuote() = Observable.apply[String] {
obs =>
val url = "http://www.iheartquotes.com/api/v1/random?" +
"show_permalink=false&show_source=false"
obs.onNext(Source.fromURL(url).getLines.mkString)
obs.onCompleted()
Subscription
}
import Observable._
def errorMessage = items("Retrying...") ++ error(new Exception)
def quoteMessage(): Observable[String] = for {
text <- randomQuote()
message <- if (text.size < 50) items(text)
else errorMessage
} yield message
quoteMessage().retry(5).subscribe(str => println(str))
val status = Observable.items("1", "2") ++ Observable.error(new Exception)
val fixedStatus = status.onErrorReturn(e => "exception")
fixedStatus.subscribe(str => println(str))
val continuedStatus = status.onErrorResumeNext(e =>
Observable.items("4", "5"))
continuedStatus.subscribe(str => println(str))
Concurrent Application Development using Scala
Concurrent Application Development using Scala
Concurrent Application Development using Scala

Concurrent Application Development using Scala

  • 1.
    Concurrent Application Development usingScala Sergei Semenchuk https://github.com/binjip978/ConcTalk
  • 2.
  • 3.
    def withdrawMoney(user: String, password:String, amount: Int): Money = { // some logic Money(amount) } def buyBook(name: String, cash: Money): Book = { // some logic Book("Functional Programming in Scala") } val cash = withdrawMoney("user1", "password2", 100) val book = buyBook("Functional Programming in Scala", cash) println(book)
  • 4.
    trait Try[+T] case classSuccess[+T](value: T) extends Try[T] case class Failure(e: Throwable) extends Try[Nothing] val success = Success(100) success match { case Success(v) => println(v) case Failure(e) => println(s"Error: $e") }
  • 5.
    val v =Try { if (scala.util.Random.nextBoolean() == true) 12 else 1 / 0 } v match { case Success(v) => println(v) case Failure(e) => println("Error!") }
  • 6.
    def withdrawMoney(user: String, password:String, amount: Int): Try[Money] = { Try(Money(amount)) } def buyBook(name: String, cash: Money): Try[Book] = { Try(Book("Functional Programming in Scala")) } withdrawMoney("user1", "password2", 100) match { case Success(cash) => { buyBook("Functional Programming in Scala", cash) match { case Success(book) => println(book) case Failure(e) => println(s"Error occurred: $e") } } case Failure(e) => println(s"Error occurred: $e") }
  • 7.
    case class Money(amount:Int) case class Book(title: String) def withdrawMoney(user: String, password: String, amount: Int): Try[Money] = { // some logic Try(Money(amount)) } def buyBook(name: String, cash: Money): Try[Book] = { // some logic Try(Book("Functional Programming in Scala")) } for { cash <- withdrawMoney("user1", "password2", 100) book <- buyBook("Functional Programming in Scala", cash) } println(book)
  • 8.
    case class Money(amount:Int) case class Book(title: String) def withdrawMoney(user: String, password: String, amount: Int): Try[Money] = { // some logic Try(Money(amount)) } def buyBook(name: String, cash: Money): Try[Book] = { // some logic Try(Book("Functional Programming in Scala")) } val book = withdrawMoney("user1", "password2", 100) .flatMap(cash => buyBook("Functional Programming in Scala", cash)) book.foreach(b => println(b)) }
  • 9.
    trait Option[+A] case classSome[+A](v: A) extends Option[A] case object None extends Option[Nothing] def unit[A](v: A): Option[A] = { Some(v) } def flatMap[A, B](op: Option[A])(f: A => Option[B]): Option[B] = op match { case Some(v) => f(v) case None => None } def map[A, B](op: Option[A])(f: A => B): Option[B] = { flatMap(op)(x => unit(f(x))) }
  • 10.
    The Four EssentialEffects In Programming One Many Synchronous T/Try[T] Iterable[T] Asynchronous Future[T] Observable[T]
  • 11.
  • 12.
    //def apply[T](b: =>T)(implicite: ExecutionContext): Future[T] val f = Future { println("Hello World!") } println(f.isCompleted) Thread.sleep(1000) println(f.isCompleted)
  • 13.
    def getUrlSpec(): Future[List[String]]= Future { val url = "http://www.w3.org/Addressing/URL/url-spec.txt" val f = scala.io.Source.fromURL(url) try { f.getLines().toList } finally { f.close() } } def find(lines: List[String], keyword: String):String = { lines.zipWithIndex.collect { case (line, n) if (line.contains(keyword)) => (n, line) } mkString("n") } val f = getUrlSpec() f.foreach { case (lines) => println(find(lines, “telnet")) } Thread.sleep(5000)
  • 14.
    val f: Future[Int]= Future { 1 / 0 } f onComplete { case Success(v) => println("Surprise!") case Failure(e) => println(s"Error: $e") } Thread.sleep(1000)
  • 15.
    val f1: Future[Int]= Future { 1345 } val f2: Future[Int] = Future { 2356 } val f3: Future[Int] = Future { 4563 } val comp1: Future[Int] = f1.flatMap(v1 => f2.flatMap(v2 => f3.map(v3 => v1 + v2 + v3))) val comp2: Future[Int] = for { v1 <- f1 v2 <- f2 v3 <- f3 } yield v1 + v2 + v3 //comp1 === comp2 comp1.onSuccess { case(x: Int) => println(x) } comp2.onSuccess { case(x: Int) => println(x) } Thread.sleep(1000) }
  • 16.
    val f1 =Future { 1 } val f2 = Future { 1 / 0 } val f3 = Future { 2 } val c = for { v1 <- f1 v2 <- f2 v3 <- f3 } yield v1 + v2 + v3 c onComplete { case Success(v) => println(v) case Failure(e) => println(s"error $e") } Thread.sleep(1000)
  • 17.
    def getRandonName =Future { "John" } def getIdByName(name: String) = Future { 12 } def getDepotIdById(id: Int) = Future { 34 } def getDepotName(id: Int) = Future { "A depot" } val f = for { name <- getRandonName userId <- getIdByName(name) depotId <- getDepotIdById(userId) depotName <- getDepotName(userId) } yield s"$name from $depotName" f.onSuccess { case (v) => println(v) } Thread.sleep(1000)
  • 18.
    def getUSDQuote =Future { 1.2 } def getEURQuote = Future { 0.8 } val p = for { usd <- getUSDQuote eur <- getEURQuote if (eur > usd) } yield usd p onFailure { case (e) => println("Error: " + e) } Thread.sleep(1000)
  • 19.
    val f1: Future[Int]= Future { 1 / 0 } val f2: Future[Any] = f1.recover { case (exp) => s"error happend: $exp" } f2.onComplete { case Success(v) => println(s"if success: $v") case Failure(e) => println(s"if failure: $e") } Thread.sleep(1000)
  • 20.
    val p =Promise[String] val q = Promise[String] p.future foreach { case x => println(x)} q.future.failed foreach { case e => println(s"error: " + e)} p.complete(Success("Promise complete")) q.complete(Failure(new Exception)) val z = Promise[Int] z.future onComplete { case Success(v) => println(v) case Failure(e) => println(s"Error: $e") } z.complete(Try(1 / 0))
  • 21.
    def first[T](xs: List[Future[T]]):Future[T] = { val p = Promise[T] for { x <- xs } p.tryCompleteWith(x) p.future } val f = first(List(Future{ Thread.sleep(2000); 12 }, Future { new Exception })) f.foreach { case x => println(x) }
  • 22.
    val urlSpecSize =Future { val url = "http://www.scala-lang.org" scala.io.Source.fromURL(url).size } // how much we should wait until exception val size = Await.result(urlSpecSize, 10 seconds) println(size)
  • 23.
  • 24.
    val observable: Observable[String]= Observable.items("A", "B", "C") observable.subscribe(str => println(str.toLowerCase)) observable.subscribe(str => println(str * 7))
  • 25.
    val o: Observable[Long]= Observable.timer(2 second) o.subscribe(x => println(x)) o.subscribe(x => println(x + 1000))
  • 26.
    val ex =new RuntimeException val observable: Observable[Int] = Observable.items(0, 1, 2) ++ Observable.error(ex) ++ Observable.items(3, 4) observable.subscribe( value => println(value), error => println(s"an error occurred: $error") )
  • 27.
    val countries =List("Germany", "US", "Japan") val observable = Observable.from(countries) observable.subscribe(new Observer[String] { override def onNext(c: String) = println(s"Nice to live in $c”) override def onError(e: Throwable) = println(“error!!!") override def onCompleted() = println("That all list!") })
  • 28.
    // def create(f:Observer[T] => Subscription): Observable[T] val vms = Observable.apply[String] { obs => obs.onNext("JVM") obs.onNext("LLVM") obs.onNext("Dalvik") obs.onCompleted() Subscription } vms.subscribe(str => println(str)) }
  • 29.
    val f =Future("Future") val observable = Observable.apply[String] { obs => f onComplete { case Success(v) => { obs.onNext(v) obs.onCompleted() } case Failure(e) => { obs.onError(e) } } Subscription } observable.subscribe(str => println(str))
  • 30.
    def coldObserver(directory: String):Observable[String] = { Observable.apply[String] { obs => val fileMonitor = new FileAlterationMonitor(1000) val fileObs = new FileAlterationObserver(directory) val fileListener = new FileAlterationListenerAdaptor { override def onFileChange(file: java.io.File): Unit = { obs.onNext(file.getName) } } fileObs.addListener(fileListener) fileMonitor.addObserver(fileObs) fileMonitor.start() Subscription { fileMonitor.stop() } } }
  • 31.
    def hotObserver(directory: String):Observable[String] = { val fileMonitor = new FileAlterationMonitor(1000) val fileObs = new FileAlterationObserver(directory) fileMonitor.addObserver(fileObs) Observable.apply[String] { obs => val fileListener = new FileAlterationListenerAdaptor { override def onFileChange(file: java.io.File): Unit = { obs.onNext(file.getName) } } fileObs.addListener(fileListener) Subscription { fileObs.removeListener( fileListener) } } }
  • 32.
    val odds =Observable.interval(0.5 seconds) .filter(x => x % 2 == 1) .map(x => s"num $x") .take(5) odds.subscribe(str => println(str))
  • 33.
    def fetchQuote(): Future[String]= Future { blocking { val url = “http://www.iheartquotes.com/api/v1/random?" + "show_permalink=false&show_source=false" Source.fromURL(url).getLines().mkString } } def fetchQuoteObservable(): Observable[String] = { Observable.from(fetchQuote()) } def quotes(): Observable[Observable[String]] = { Observable.interval(1 second).take(5).map { n => fetchQuoteObservable().map(txt => s"$n) $txt") } } val concat: Observable[String] = quotes().concat concat.subscribe(q => println(q)) / val flatten: Observable[String] = quotes().flatten // val qs: Observable[String] = for { n <- Observable.interval(1 second).take(5) txt <- fetchQuoteObservable() } yield s"$n) $txt" qs.subscribe(q => println(q))
  • 34.
    def randomQuote() =Observable.apply[String] { obs => val url = "http://www.iheartquotes.com/api/v1/random?" + "show_permalink=false&show_source=false" obs.onNext(Source.fromURL(url).getLines.mkString) obs.onCompleted() Subscription } import Observable._ def errorMessage = items("Retrying...") ++ error(new Exception) def quoteMessage(): Observable[String] = for { text <- randomQuote() message <- if (text.size < 50) items(text) else errorMessage } yield message quoteMessage().retry(5).subscribe(str => println(str))
  • 35.
    val status =Observable.items("1", "2") ++ Observable.error(new Exception) val fixedStatus = status.onErrorReturn(e => "exception") fixedStatus.subscribe(str => println(str)) val continuedStatus = status.onErrorResumeNext(e => Observable.items("4", "5")) continuedStatus.subscribe(str => println(str))