Of course one could collect the system time at the first line of the Future's body. But:
Is it possible to know that time without having access to the future's code. (In my case the method returning the future is to be provided by the user of the 'framework'.)
def f: Future[Int] = ...
def magicTimePeak: Long = ???
The Future
itself doesn't really know this (nor was it designed to care). It's all up to the executor when the code will actually be executed. This depends on whether or not a thread is immediately available, and if not, when one becomes available.
You could wrap Future
, to keep track of it, I suppose. It would involve creating an underlying Future
with a closure that changes a mutable var within the wrapped class. Since you just want a Long
, it would have to default to zero if the Future
hasn't begun executing, though it would be trivial to change this to Option[Date]
or something.
class WrappedFuture[A](thunk: => A)(implicit ec: ExecutionContext) {
var started: Long = 0L
val underlying = Future {
started = System.nanoTime / 1000000 // milliseconds
thunk
}
}
To show that it works, create a fixed thread pool with one thread, then feed it a blocking task for say, 5 seconds. Then, create a WrappedFuture
, and check it's started
value later. Note the difference in the logged times.
import java.util.concurrent.Executors
import scala.concurrent._
val executorService = Executors.newFixedThreadPool(1)
implicit val ec = ExecutionContext.fromExecutorService(executorService)
scala> println("Before blocked: " + System.nanoTime / 1000000)
Before blocked: 13131636
scala> val blocker = Future(Thread.sleep(5000))
blocker: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@7e5d9a50
scala> val f = new WrappedFuture(1)
f: WrappedFuture[Int] = WrappedFuture@4c4748bf
scala> f.started
res13: Long = 13136779 // note the difference in time of about 5000 ms from earlier
If you don't control the creation of the Future
, however, there is nothing you can do to figure out when it started.