Reputation: 13686
Is there a way to directly get the value out of a successful promise?
Is it really necessary to connect a future
to the promise, for that?
scala> import scala.concurrent._
import scala.concurrent._
scala> val result = Promise[Int]
result: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala> result success 3
res0: result.type = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala> result
res1: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$DefaultPromise@2b5fa85f
scala> result.isCompleted
res4: Boolean = true
scala> result.value
<console>:12: error: value value is not a member of scala.concurrent.Promise[Int]
result.value
^
scala> result.future.value.get.get
res6: Int = 3
I am considering using a promise for thread-safe "assign once" semantics. The promise object looks lean enough in the scala.concurrent source, and as far as I understand it is thread safe. I'd rather however, avoid adding another object (a future). I could not find a getter for the success value of a promise.
Upvotes: 3
Views: 2045
Reputation: 108101
p.future == p
so don't worry about the extra allocation.
Promise
and Future
are complimentary. The former represents the write (once) side of the computation, while the latter is the read side.
So, in order to read a value from a Promise
you will always need to do it via a Future
.
On the other hand, it's worth noting that despite the abstract design, the implementation is quite efficient and Promise
and Future
are not separate entities. Here's the implementation of the future
of Promise
private[concurrent] trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T] {
def future: this.type = this
}
So, you can see that p.future
is actuall the same as p
, and it simply gets a different semantic.
Bottom line, you can access future
from promise and you won't be paying any additional cost in terms of instance allocations.
Also, you can make the syntax nicer if you wish
scala> implicit class DirectAccessPromise[A](val p: Promise[A]) extends AnyVal {
| def get = p.future.value.get.get
| }
defined class DirectAccessPromise
scala> val p = Promise.successful(42)
res0: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise$KeptPromise@5e8c92f4
scala> p.get
res1: Int = 42
Note that since the wrapper is a value class, you won't be paying any extra-instantiation price
Upvotes: 9
Reputation: 3519
The DefaultPromise returns itself as the future, so you aren't making an extra allocation. Even if you were, the cost of the thread safety is likely much greater.
Upvotes: 4