-2

My Scenario is like below:

Step1: x =def sum(a,b)

Step2: Thread.sleep(1s)

Step3: y =def subtract(a,b)

Step4: Thread.sleep(2s)

Step5: On successfull completion of above steps perform z = multiple(x,y)

I need to implement this scenario using futures in Scala. Please help. I Tried this code but it is not working.

import scala.util.{Failure, Success}
def sum(a:Int ,b:Int) = a+b
def sub(c:Int, d:Int) = c-d
def mul(e: Int, f: Int) = e*f

val Sum1= Future {sum(2,3); Thread.sleep(1000)}

val SumFinal=Sum1.onComplete({
case Success(result) => println(result)
case Failure(e) => println("failed: " + e)
})

val Subt1 = Future {sub(5,3);Thread.sleep(2000)}
val SubtFinal = Subt1.onComplete({
case Success(result) => result
case Failure(e) => println("failed: " + e)
})

val Mul1= mul(SumFinal,SubtFinal)
println(Mul1)
  • You can wrap the computation in future. Like def sum(a: Int, b: Int) = Future { a + b } – Mahesh Chand Dec 27 '18 at 10:33
  • Tried this but not working: `code` import scala.util.{Failure, Success} def sum(a:Int ,b:Int) = a+b def sub(c:Int, d:Int) = c-d def mul(e: Int, f: Int) = e*f val Sum1= Future {sum(2,3); Thread.sleep(1000)} val SumFinal=Sum1.onComplete({ case Success(result) => println(result) case Failure(e) => println("failed: " + e) }) val Subt1 = Future {sub(5,3);Thread.sleep(2000)} val SubtFinal = Subt1.onComplete({ case Success(result) => result case Failure(e) => println("failed: " + e) }) val Mul1= mul(SumFinal,SubtFinal) print(Mul1) `code` – saurabh verma Dec 27 '18 at 10:51
  • Check my answer – Mahesh Chand Dec 27 '18 at 11:50

2 Answers2

0

Problem 1:

The result of e.g. Future {sub(5,3);Thread.sleep(2000)} is the value returned by Thread.sleep, which is () in Scala. Just change the order: Future {Thread.sleep(2000); sub(5,3)} will finish with the result 2 after 2 seconds. If you really want to put sleep after the calculation, just store the result in a variable:

Future {
  val res = sub(5,3)
  Thread.sleep(2000)
  res
}

Problem 2:

SumFinal and SubtFinal are again () because that's what onComplete returns. Instead you can combine two futures (or more, or modify one, etc. etc.) and get a future back. One way would be (after fixing problem 1)

val Mul1 = Sum1.zipWith(Sum2)(mul)
Mul1.onComplete {
  ...
}
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Thnx for response Alexey. Your 1st part is correct, but the real problem is how to pass the Sum1 and Subt1 to mul method which is expecting integers in order to perform multiplication but Sum1 and Subt1 are returning Future[Int] – saurabh verma Dec 27 '18 at 11:52
  • You can't pass them to `mul` itself. That's why you need `zipWith` as shown in the second piece of code. – Alexey Romanov Dec 27 '18 at 12:04
0

Problem with your approach is that onComplete returns unit. That's why you don't get any result. So, subFimal and sumFinal has nothing in it.

scala> def sum(a: Int, b: Int) = Future { a + b }
sum: (a: Int, b: Int)scala.concurrent.Future[Int]

scala> def sub(a: Int, b: Int) = Future { a - b }
sub: (a: Int, b: Int)scala.concurrent.Future[Int]

scala> def mul(a: Int, b: Int) = Future { a * b }
mul: (a: Int, b: Int)scala.concurrent.Future[Int]

scala> for {
     | a <- sum(2,3)
     | b <- sub(10, 7)
     | c <- mul(a, b)
     | } yield c
res0: scala.concurrent.Future[Int] = Future(<not completed>)

scala> res0
res1: scala.concurrent.Future[Int] = Future(Success(15))
Mahesh Chand
  • 3,158
  • 19
  • 37
  • Thnx Mahesh. This is working fine. Just to add a little detail, i also need to add a sleep(1000) after sum and subtract so i modified the functions definition to def sum(a:Int ,b:Int) = Future{val res=a+b ; Thread.sleep(1000); res} def sub(c:Int, d:Int) = Future{val res=c-d; Thread.sleep(2000); res} . Can you tell me how to confirm that sum and sub function completes before mul function and perform exception handling in case anything happens. – saurabh verma Dec 27 '18 at 12:20
  • You can ensure whether the future is completed or not using the isCompelted method. It returns boolean. – Mahesh Chand Dec 27 '18 at 12:47