Making it impossible to complete a future after its expired, and not run onComplete callbacks if it hasnt been completed before expiry, fixing ticket #811

This commit is contained in:
Viktor Klang 2011-04-27 16:52:19 +02:00
parent 2da27123ac
commit 800840719f
2 changed files with 19 additions and 3 deletions

View file

@ -343,6 +343,20 @@ class FutureSpec extends JUnitSuite {
}
}
@Test def shouldNotAddOrRunCallbacksAfterFailureToBeCompletedBeforeExpiry {
val latch = new StandardLatch
val f = new DefaultCompletableFuture[Int](0)
Thread.sleep(25)
f.onComplete( _ => latch.open ) //Shouldn't throw any exception here
assert(f.isExpired) //Should be expired
f.complete(Right(1)) //Shouldn't complete the Future since it is expired
assert(f.value.isEmpty) //Shouldn't be completed
assert(!latch.isOpen) //Shouldn't run the listener
}
@Test def lesslessIsMore {
import akka.actor.Actor.spawn
val dataflowVar, dataflowVar2 = new DefaultCompletableFuture[Int](Long.MaxValue)

View file

@ -664,7 +664,7 @@ class DefaultCompletableFuture[T](timeout: Long, timeunit: TimeUnit) extends Com
def complete(value: Either[Throwable, T]): DefaultCompletableFuture[T] = {
_lock.lock
val notifyTheseListeners = try {
if (_value.isEmpty) {
if (_value.isEmpty && !isExpired) { //Only complete if we aren't expired
_value = Some(value)
val existingListeners = _listeners
_listeners = Nil
@ -685,8 +685,10 @@ class DefaultCompletableFuture[T](timeout: Long, timeunit: TimeUnit) extends Com
_lock.lock
val notifyNow = try {
if (_value.isEmpty) {
_listeners ::= func
false
if(!isExpired) { //Only add the listener if the future isn't expired
_listeners ::= func
false
} else false //Will never run the callback since the future is expired
} else true
} finally {
_lock.unlock