1
votes

I have a method that is supposed to go over a Future and return a Tuple. Here it is:

  private def myMethod(id: Long): Future[(Double, Double)] = {
    val result = for {
      someValue <- run { getFromDb(id).headOption }
      value     <- someValue
    } yield {
      value.valueType match {
        case ValueType.TypeA => (1.0, 1.0)
        case ValueType.TypeB => (2.0, 2.0)
      }
    }
  }

Here is my run method:

  private def run[R](dbio: slick.dbio.DBIOAction[R, slick.dbio.NoStream, scala.Nothing]) = async {
    await(db.run(dbio))
  }

It uses the Scala Async library to time my calls to the database!

the getFromDB method is just doing a query:

def getFromDb(myId: Long) {
  MyTableQuery.filter(_.id === myId)
}

It complaints that myMethod returns a Future[Nothing]. I do not see any problems here. Any clues as to what might not satisfy the return type that I'm looking for?

1
Isn't async {await(db.run(dbio))} the same as just db.run(dbio) ?Régis Jean-Gilles
Yes, but that is not the problem! When I have multiple calls to the database, I can time it to run sequentially using the run method!joesan
Understood. What is the return type of run? Because your are flatMapping over the return value once more, suggesting that you have something like a Future[Future[T]] as a return value, which seems odd.Régis Jean-Gilles
The return type of run is Future[R]joesan
...and R is thus inferred from getFromDb, whose definition is also missing. Please post a complete snippet.Régis Jean-Gilles

1 Answers

4
votes

Here's a simplified version which exhibits the same fault:

def method: Future[(Double, Double)] = {
  val result = for {
    someValue <- Future("a")
    value     <- Future("b")
  } yield {
    value match {
      case "a" => (1.0, 1.0)
      case "b" => (2.0, 2.0)
    }
  }
}

The problem is that you are capturing the return type in the result value, so the method has no return type. A valid form of this simplified function would be either of the following:

def method: Future[(Double, Double)] = {
  val result = for {
    someValue <- Future("a")
    value     <- Future("b")
  } yield {
    value match {
      case "a" => (1.0, 1.0)
      case "b" => (2.0, 2.0)
    }
  }
  result
}

Or:

def method: Future[(Double, Double)] = {
  for {
    someValue <- Future("a")
    value     <- Future("b")
  } yield {
    value match {
      case "a" => (1.0, 1.0)
      case "b" => (2.0, 2.0)
    }
  }
}