Skip to content

Instantly share code, notes, and snippets.

@nkallen
Created August 12, 2010 19:03
Show Gist options
  • Save nkallen/521505 to your computer and use it in GitHub Desktop.
Save nkallen/521505 to your computer and use it in GitHub Desktop.
class NotifyingFuture[A] extends Future[A] {
import NotifyingFuture._
private var result: Option[A] = None
private val computations = new ArrayBuffer[A => Unit]
def setResult(result: A) {
setResultIfEmpty(result) || {
throw new ImmutableResult("Result set multiple times: " + result)
}
}
private def isSet(onSet: A => B)(onEmpty: => B)(onWasSet: A => B)(onWasEmpty: => B) {
result map(onSet) orElse {
val wasSet = synchronized {
result map(onSet) getOrElse(onEmpty)
}
if (wasSet) onWasSet else onWasEmpty
}
}
def setResultIfEmpty(result: A) = {
isSet {} {
this.result = Some(result)
} {
false
} {
computations foreach(_(result))
true
}
}
def respond(k: A => Unit) {
isSet {} {} {
k(result)
} {
computations += k
}
}
}
class NotifyingFuture[A] extends Future[A] {
import NotifyingFuture._
private var result: Option[A] = None
private val computations = new ArrayBuffer[A => Unit]
def setResult(result: A) {
setResultIfEmpty(result) || {
throw new ImmutableResult("Result set multiple times: " + result)
}
}
def setResultIfEmpty(result: A) = {
val didSetResult = synchronized {
result map(false) getOrElse {
this.result = Some(result)
true
}
}
if (didSetResult) computations foreach(_(result))
didSetResult
}
def respond(k: A => Unit) {
result map(k) orElse {
val isDefined = synchronized {
result.isDefined || { computations += k; false }
}
if (isDefined) k(result.get)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment