DEV Community

Discussion on: Go for Java developers (or is the Java concurrency that bad?!)

Collapse
 
tobias_salzmann profile image
Tobias Salzmann • Edited

Nice comparison!

Having a sane built-in concurrency model is definitely a big plus for a language. That's definitely one of the things where go excels at.

I do like future-based async code, because it tends to be very clean and testable. Java's implementation however, is a big mess with very questionable design choices.

Here's a quick draft in scala, that intention wise is very close to your Java code, but using Scala's Future.sequence and Future.firstCompletedOf, avoiding low level concurrency completely.

def web(query: String): Future[String] = ???
def image(query: String): Future[String] = ???
def video(query: String): Future[String] = ???
def webReplicated(query: String): Future[String] = ???
def imageReplicated(query: String): Future[String] = ???
def videoReplicated(query: String): Future[String] = ???
def failAfter(timeOut: FiniteDuration): Future[Nothing] = ???


def google(query: String): Future[Seq[String]] = {
  Future.sequence(Seq(web(query), image(query), video(query)))
}

def googleWithTimeout(query: String, timeOut: FiniteDuration): Future[Seq[String]] = {
  Future.firstCompletedOf(Seq(
    Future.sequence(Seq(web(query), image(query), video(query))),
    failAfter(timeOut)
  ))
}

def googleWithTimeoutReplicated(query: String, timeOut: FiniteDuration): Future[Seq[String]] = {
  Future.firstCompletedOf(Seq(
    Future.sequence(Seq(
      Future.firstCompletedOf(Seq(web(query), webReplicated(query))),
      Future.firstCompletedOf(Seq(image(query), imageReplicated(query))),
      Future.firstCompletedOf(Seq(video(query), videoReplicated(query)))
    )),
    failAfter(timeOut)
  ))
}

If I were forced to implement this in Java, I would implement sequence (using allOf) and firstCompletedOf (using anyOf) instead of using concurrent datastructures.

Collapse
 
netvl profile image
Vladimir Matveev

I think you can write the third function in an even shorter way with Future.traverse instead of Future.sequence:

Future.firstCompletedOf(Seq(
  Future.traverse(Future.firstCompletedOf)(Seq(
    Seq(web(query), webReplicated(query)),
    Seq(image(query), imageReplicated(query)),
    Seq(video(query), videoReplicated(query))
  )),
  failAfter(timeOut)
))

I didn't expect this, but I discovered that Future.traverse is really handy in lots of situations.

Collapse
 
napicella profile image
Nicola Apicella

Thanks for writing down the Scala way.
I have not written any significant piece of code in Scala, but every time I stumble in something written in it, it looks just so elegant.
You made me think I should learn more about it :)

By the way, your scala code would make a great response post :)