-
Notifications
You must be signed in to change notification settings - Fork 2
/
UsefulFuture.scala
71 lines (61 loc) · 1.91 KB
/
UsefulFuture.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package asynchronous
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.{Duration, TimeUnit}
import scala.concurrent.{Await, ExecutionContext, Future}
import scala.util.{Failure, Success}
object UsefulFuture {
/**
* Contains functions, affecting futures.
*
* Purity project by Daniil Tekunov.
*/
implicit class UsefulFuture[T](future: Future[T])(implicit ec: ExecutionContext) {
/**
* Applies a given function to a result of a future without affecting the future itself
*/
def bypassOnComplete[A](function: T => A): Future[T] = {
future onComplete {
case Success(outcome) => function(outcome)
case Failure(_) => Future.failed(new Exception)
}
future
}
/**
* Throws a given exception if a future failed and applies a given function to it
*/
def ifFailure(functionFail: => Unit, exception: Option[Throwable] = None): Future[T] = {
future transformWith {
case Failure(ex) =>
functionFail
Future.failed(exception getOrElse ex)
case _ => future
}
}
/**
* Returns the result of a future within given time
*/
def result(awaitTime: Long, timeUnit: TimeUnit = TimeUnit.MICROSECONDS): T =
Await.result(future, Duration(awaitTime, timeUnit))
/**
* Completes first future and returns second future if first one completes
*/
def completeAndThen(anotherFuture: Future[T]): Future[T] = {
future andThen {
case Success(_) => anotherFuture
case Failure(ex) => ex
}
}
/**
* Completes first future and then completes second future
*/
def completeAndThenComplete(anotherFuture: Future[T]): Future[T] = {
future andThen {
case Success(_) => anotherFuture andThen {
case Success(x) => x
case Failure(ex) => ex
}
case Failure(ex) => ex
}
}
}
}