I'm writing a server end program using Twitter Finagle. I do not use the full Twitter server stack, just the part that enables asynchronous processing (so Future, Function, etc). I want the Future objects to have timeouts, so I wrote this:
Future<String> future = Future.value(some_input).flatMap(time_consuming_function1);
future.get(Duration.apply(5, TimeUnit.SECONDS));
time_consuming_function1
runs for longer than 5 seconds. But future
doesn't time out after 5 seconds and it waits till time_consuming_function1
has finished.
I think this is because future.get(timeout)
only cares about how long the future
took to create, not the whole operation chain. Is there a way to timeout the whole operation chain?
Basically if you call map/flatMap on a satisfied Future, the code is executed immediately.
In your example, you're satisfying your future immediately when you call Future.value(some_input)
, so flatMap executes the code immediately and the call to get
doesn't need to wait for anything. Also, everything is happening in one thread. A more appropriate use would be like this:
import scala.concurrent.ops._
import com.twitter.conversions.time._
import com.twitter.util.{Future,Promise}
val p = new Promise[String]
val longOp = (s: String) => {
val p = new Promise[String]
spawn { Thread.sleep(5000); p.setValue("Received: " + s) }
p
}
val both = p flatMap longOp
both.get(1 second) // p is not complete, so longOp hasn't been called yet, so this will fail
p.setValue("test") // we set p, but we have to wait for longOp to complete
both.get(1 second) // this fails because longOp isn't done
both.get(5 seconds) // this will succeed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With