Skip to content

Instantly share code, notes, and snippets.

@felixbr
Last active February 4, 2020 23:08
Show Gist options
  • Save felixbr/c72c66f36357ac1149096aa47f1cb8bc to your computer and use it in GitHub Desktop.
Save felixbr/c72c66f36357ac1149096aa47f1cb8bc to your computer and use it in GitHub Desktop.
Google 3.0 in Scala
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.util.Random
// go original from here: https://github.com/golang/talks/blob/master/content/2012/concurrency/support/google3.0.go
object SearchBackend extends App {
type Query = String
type Result = String
type Search = Query => Future[Result]
val webBackends = List(
fakeSearch("web1"),
fakeSearch("web2")
)
val imageBackends = List(
fakeSearch("image1"),
fakeSearch("image2")
)
val videoBackends = List(
fakeSearch("video1"),
fakeSearch("video2")
)
def search(query: Query): Future[List[Result]] = {
val results = List(
firstResult(query, webBackends),
firstResult(query, imageBackends),
firstResult(query, videoBackends)
)
Future.sequence(results)
}
private def firstResult(query: Query, backendReplicas: List[Search]): Future[Result] = {
val timeoutFuture = Future { Thread.sleep(80); "timeout" } // or use akka.pattern.after, monix.execution.FutureUtils, etc.
val searches: List[Future[Result]] = backendReplicas.map(r => r(query))
Future.firstCompletedOf(timeoutFuture :: searches)
}
private def fakeSearch(kind: String): Search =
{ query =>
Future {
Thread.sleep(Random.nextInt(100).toLong)
s"$kind result for '$query'"
}
}
// using it
Await.result(search("cute cats"), 5.seconds).foreach(println)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment